Ejemplo n.º 1
0
    def install_path(self, datapath, tcp_pkt, ip, cesta):
        parser = datapath.ofproto_parser
        fullpath = copy.deepcopy(cesta)
        tmppath = cesta[1:-1]
        print "Installing path from", ip.src, "to", ip.dst, "and backwards. Path is: ", fullpath
        for s in tmppath:
            match = parser.OFPMatch(eth_type=0x0800,
                                    ip_proto=6,
                                    ipv4_src=ip.src,
                                    ipv4_dst=ip.dst,
                                    tcp_src=tcp_pkt.src_port,
                                    tcp_dst=tcp_pkt.dst_port)
            next = fullpath[fullpath.index(s) + 1]
            out_port = self.net[s][next]['port']
            actions = [parser.OFPActionOutput(out_port)]
            self.add_flow(get_datapath(self, s), 4, match, actions)

            match = parser.OFPMatch(eth_type=0x0800,
                                    ip_proto=6,
                                    ipv4_src=ip.dst,
                                    ipv4_dst=ip.src,
                                    tcp_src=tcp_pkt.dst_port,
                                    tcp_dst=tcp_pkt.src_port)
            prev = fullpath[fullpath.index(s) - 1]
            out_port = self.net[s][prev]['port']
            actions = [parser.OFPActionOutput(out_port)]
            self.add_flow(get_datapath(self, s), 4, match, actions)
Ejemplo n.º 2
0
    def _handle_arp_packets(self, switches, datapath, dpid_src, pkt, src, dst,
                            in_port):
        """Handling of an ARP packet."""
        arp_packet = pkt.get_protocol(arp.arp)
        arp_src_ip = arp_packet.src_ip
        arp_dst_ip = arp_packet.dst_ip

        if arp_packet.opcode == 1:
            #self.logger.info("ARP request")
            if arp_dst_ip in self.ip_to_mac:
                #self.logger.info("The address is inside the IP TO MAC table")
                src_ip = arp_dst_ip
                dst_ip = arp_src_ip
                src_mac = self.ip_to_mac[arp_dst_ip]
                dst_mac = src
                out_port = in_port
                # Send an ARP reply
                opcode = 2
                self.send_arp(datapath, opcode, src_mac, src_ip, dst_mac,
                              dst_ip, out_port)
                #self.logger.info("Packet in %s %s %s %s", src_mac, src_ip, dst_mac, dst_ip)
            else:
                #self.logger.info("The address is NOT inside the IP TO MAC table")
                src_ip = arp_src_ip
                dst_ip = arp_dst_ip
                src_mac = src
                dst_mac = dst
                self.ip_to_mac.setdefault(src_ip, {})
                self.ip_to_mac[src_ip] = src_mac
                opcode = 1
                for id_switch in switches:
                    datapath_dst = get_datapath(self, id_switch)
                    for port in range(1, NUMBER_OF_SWITCH_PORTS + 1):
                        if self.port_occupied[id_switch][port] == 0:
                            out_port = port
                            if id_switch == dpid_src:
                                if out_port != in_port:
                                    self.send_arp(datapath_dst, opcode,
                                                  src_mac, src_ip, dst_mac,
                                                  dst_ip, out_port)
                            else:
                                self.send_arp(datapath_dst, opcode, src_mac,
                                              src_ip, dst_mac, dst_ip,
                                              out_port)
        else:
            #self.logger.info("ARP reply")
            src_ip = arp_src_ip
            dst_ip = arp_dst_ip
            src_mac = src
            dst_mac = dst
            if arp_dst_ip in self.ip_to_mac:
                self.ip_to_mac.setdefault(src_ip, {})
                self.ip_to_mac[src_ip] = src_mac
            opcode = 2
            out_port = self.mac_to_port[self.mac_to_dpid[dst_mac]][dst_mac]
            datapath_dst = get_datapath(self, self.mac_to_dpid[dst_mac])
            self.send_arp(datapath_dst, opcode, src_mac, src_ip, dst_mac,
                          dst_ip, out_port)
Ejemplo n.º 3
0
    def handle_host_add(self, ev):  # 主机上线
        """
        Event handler indiciating a host has joined the network
        This handler is automatically triggered when a host sends an ARP response.
        """
        host = ev.host

        self.logger.warn("Host Added:  %s (IPs:  %s) on switch%s/%s (%s)",
                         host.mac, host.ipv4, host.port.dpid,
                         host.port.port_no, host.port.hw_addr)

        # 1 记录这个主机对应的switch 增加转发表
        # 相当于终端
        self.belong[host.mac] = (host.port.dpid, host.port.port_no)
        self.add_forwaring_rule(
            ofctl_api.get_datapath(self, dpid=host.port.dpid), host.mac,
            host.port.port_no)

        # 2 更新其他switch上的转发表
        for dpid in self.res:  # 最短路的计算结果?
            dp = ofctl_api.get_datapath(self, dpid=dpid)

            # 如果是自己 就跳过
            if dpid == host.port.dpid:
                continue

            # 从图上更新其他switch
            self.add_forwaring_rule(dp, host.mac,
                                    self.res[dpid][host.port.dpid])

        # JL: 增加ip-mac对应
        self.ip_mac_dict[host.ipv4[0]] = host.mac

        self.tm.add_host(host)

        # 增加switch-host记录
        print("[DEBUG ADD] add switch-host before",
              (host.port.dpid not in self.switch_contain_host))
        if host.port.dpid not in self.switch_contain_host:
            # 如果这个host相连的switch还没有被记录过
            self.switch_contain_host[host.port.dpid] = []

        self.switch_contain_host[host.port.dpid].append(
            (host.mac, host.port.port_no))

        print("[BELONG]", self.belong)

        self.calc_spanning_tree()

        self.one_switch_special_case()

        self.show_topology()
        self.show_shortest_path()
        self.show_spanning_tree()
Ejemplo n.º 4
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        in_port = msg.match['in_port']
        datapath = msg.datapath
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)

        if eth.ethertype == ether_types.ETH_TYPE_ARP:
            #Send arp packets out over all switches
            assert msg.buffer_id == ofp.OFP_NO_BUFFER
            arp_ = pkt.get_protocol(arp.arp)

            ctime = time.time()
            key = (arp_.hwtype, arp_.proto, arp_.hlen, arp_.plen, arp_.opcode,
                   arp_.src_mac, arp_.src_ip, arp_.dst_mac, arp_.dst_ip)
            if (ctime < self.arp.get(key, float('-inf')) + self.CONF.debounce):
                return

            self.arp.get(key, float('inf'))
            for dpid in self.topo:
                datapath = api.get_datapath(self, dpid)
                datapath.send_msg(
                    ofp_parser.OFPPacketOut(
                        datapath,
                        buffer_id=ofp.OFP_NO_BUFFER,
                        in_port=ofp.OFPP_CONTROLLER,
                        actions=[
                            ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)
                        ],
                        data=msg.data
                    )
                )

            self.arp[key] = time.time()
        elif eth.ethertype == ether_types.ETH_TYPE_IP:
            ipv4_ = pkt.get_protocol(ipv4.ipv4)
            dscp = ipv4_.tos >> 2
            if dscp != 0:
                for _,odpid,(ipt,_) in (
                    self.topo.out_edges_iter(datapath.id, data='pt')):
                    if ipt == in_port:
                        self.rewrite = (datapath.id, in_port)
                        msg.datapath = api.get_datapath(self, odpid)
                        replace_fields(ofp_parser, msg, in_port=dscp_in(dscp))
                        ipv4_.tos = ipv4_.tos & 3
                assert self.rewrite is not None
            self._packet_in_handler_short(ev)
            self.rewrite = None
Ejemplo n.º 5
0
    def handle_link_delete(self, ev):
        """
        Event handler indicating when a link between two switches has been deleted
        """
        link = ev.link
        src_port = link.src
        dst_port = link.dst

        print("[*] delete happened")
        self.logger.warn("Deleted Link:  switch%s/%s (%s) -> switch%s/%s (%s)",
                          src_port.dpid, src_port.port_no, src_port.hw_addr,
                          dst_port.dpid, dst_port.port_no, dst_port.hw_addr)

        self.graph.remove(src_port.dpid, dst_port.dpid)
        self.graph.remove(dst_port.dpid, src_port.dpid)
        self.shortest_path()

        # 全部flow清空
        for switch in self.switch_list:
            datapath = ofctl_api.get_datapath(self, dpid = host.port.dpid)
            empty_match = parser.OFPMatch()
            instructions = []
            flow_mod = self.remove_table_flows(datapath, 0, empty_match, instructions)
        # print "deleting all flow entries in table ", 0
            datapath.send_msg(flow_mod)

        # flow重建
        for host_mac in self.belong:
            host_port_dpid, host_port_no = self.belong[host_mac]
            self.add_forwaring_rule(
                ofctl_api.get_datapath(self, dpid=host_port_dpid),
                host_mac,
                host_port_no
            )

            for dpid in self.res: # 最短路的计算结果?
                dp = ofctl_api.get_datapath(self, dpid=dpid)

                # 如果是自己 就跳过
                if dpid == host_port_dpid:
                    continue

                # 从图上更新其他switch
                self.add_forwaring_rule(
                    dp,
                    host_mac,
                    self.res[dpid][host_port_dpid]
                )
Ejemplo n.º 6
0
    def switch_get_datapath(self, datapath_id):
        """Return a datapath object given its datapath ID.

        :param datapath_id: ID of a datapath i.e. switch ID.
        :return: Datapath object.
        """
        return api.get_datapath(self, datapath_id)
Ejemplo n.º 7
0
	def get_topology_data(self, ev):
#		"""
#		Get topology data. Links and switches.
#		"""
		switch_list = get_switch(self.topology_api_app, None)
		switches=[switch.dp.id for switch in switch_list]

		for s in switches:
			print(get_datapath(self,s))
		self.net.add_nodes_from(switches)
		print("Switches: ", switches)

		links_list = get_link(self.topology_api_app, None)
		print("Links_list from ryu: ",links_list)

		links = [(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
		print("Linky: ",links)

		self.net.add_edges_from(links)

		links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list]
		print("Linky znova: ",links)
		self.net.add_edges_from(links)
		print("Linky z programu: ",self.net.edges())
		print("Nodes z programu: ",self.net.nodes())
Ejemplo n.º 8
0
    def switch_get_datapath(self, datapath_id):
        """Return a datapath object given its datapath ID.

        :param datapath_id: ID of a datapath i.e. switch ID.
        :return: Datapath object.
        """
        return api.get_datapath(self, datapath_id)
Ejemplo n.º 9
0
    def _send_packet(self, ev):
        """
        First install drop flows if they are not there yet.
        Then send the packet through the switch
        :param ev: EventSendPacket
        """
        self.install_drop_flows()

        pkt = ev.packet
        imsi = ev.imsi
        if isinstance(pkt, (bytes, bytearray)):
            data = bytearray(pkt)
        elif isinstance(pkt, Packet):
            pkt.serialize()
            data = pkt.data
        else:
            raise ValueError('Could not handle packet of type: '
                             '{}'.format(type(pkt)))

        self.logger.debug('Tracer sending packet: %s', str(Packet(data)))
        datapath = get_datapath(self, dpid=self._datapath.id)
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser
        actions = [
            # Turn on test-packet as we're just tracing it
            ofp_parser.NXActionRegLoad2(dst=TEST_PACKET_REG,
                                        value=TestPacket.ON.value),
            # Add IMSI metadata
            ofp_parser.NXActionRegLoad2(dst=IMSI_REG, value=encode_imsi(imsi)),
            # Submit to table=0 because otherwise the packet will be dropped!
            ofp_parser.NXActionResubmitTable(table_id=0),
        ]
        datapath.send_packet_out(in_port=ofp.OFPP_LOCAL,
                                 actions=actions,
                                 data=data)
    def _set_redundancy(self, dpid, redundancy):
        self.logger.info("Setting redundancy to: {}".format(redundancy))
        datapath = get_datapath(self, dpid)
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        self.logger.info("Create OAM packet")
        # pkt = copy.deepcopy(self.config_pkt)
        pkt = packet.Packet()
        pkt.add_protocol(
            ethernet.ethernet(ethertype=ether_types.ETH_TYPE_IP,
                              dst='ff:ff:ff:ff:ff:ff',
                              src='00:00:00:00:00:0c'))
        pkt.add_protocol(
            ipv4.ipv4(dst="255.255.255.255",
                      src="0.0.0.0",
                      proto=in_proto.IPPROTO_UDP))
        pkt.add_protocol(udp.udp(dst_port=common.UDP_PORT_OAM))
        payload = struct.pack(">i", int(redundancy))
        pkt.add_protocol(payload)
        pkt.serialize()
        data = pkt.data
        in_port = ofp.OFPP_CONTROLLER
        actions = [ofp_parser.OFPActionOutput(1)]
        req = ofp_parser.OFPPacketOut(datapath, ofp.OFP_NO_BUFFER, in_port,
                                      actions, data)
        self.logger.info("Send OAM packet to encoder")
        datapath.send_msg(req)
Ejemplo n.º 11
0
    def add_group_flows(self, parser, ofproto, group_entries):
        for dpid in group_entries:
            ports = group_entries[dpid]
            for port in ports:
                entry = ports[port]
                if entry:
                    self.logger.info('entry for dpid {0}: {1}'.format(dpid, entry))
                    entry_match = entry['match']
                    datapath = api.get_datapath(self, dpid)
                    group_mod_command = ofproto.OFPGC_ADD
                    group_id = None
                    if entry_match['ipv4_dst'] in self._group_ids[dpid]:
                        group_id = self._group_ids[dpid][entry_match['ipv4_dst']]
                        group_mod_command = ofproto.OFPGC_MODIFY
                    else:
                        group_id = self.get_next_group_id(dpid, entry_match['ipv4_dst'])

                    match = parser.OFPMatch(in_port=entry_match['in_port'], eth_type=entry_match['eth_type'],
                                            ipv4_dst=entry_match['ipv4_dst'])
                    actions = [parser.OFPActionOutput(output_port) for output_port in entry['actions_output_ports']]
                    buckets = [parser.OFPBucket(actions=[action]) for action in actions]
                    req_group = parser.OFPGroupMod(datapath=datapath, command=group_mod_command,
                                                   type_=ofproto.OFPGT_ALL, group_id=group_id, buckets=buckets)
                    inst = [
                        parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                                     [parser.OFPActionGroup(group_id=group_id)])]
                    req_flow = parser.OFPFlowMod(datapath=datapath, priority=1, match=match, instructions=inst)
                    datapath.send_msg(req_group)
                    datapath.send_msg(req_flow)
Ejemplo n.º 12
0
    def one_switch_special_case(self):
        # 只有一个 switch 的时候 没有生成树
        if (len(self.switch_list) == 1):
            for switch in self.switch_list:
                for host_mac in self.belong:
                    host_port_dpid, host_port_no = self.belong[host_mac]
                    datapath = ofctl_api.get_datapath(self,
                                                      dpid=host_port_dpid)
                    match = datapath.ofproto_parser.OFPMatch(
                        dl_dst=haddr_to_bin(ETHERNET_MULTICAST),  # 这是一个广播包
                        dl_src=haddr_to_bin(host_mac),  # 来源 MAC 地址
                    )
                    actions = [
                        datapath.ofproto_parser.OFPActionOutput(i[1])
                        for i in self.switch_contain_host[host_port_dpid]
                    ]

                    ofp_parser = datapath.ofproto_parser

                    flow_mod = datapath.ofproto_parser.OFPFlowMod(
                        datapath,
                        match=match,
                        cookie=0,
                        priority=50,
                        actions=actions)
                    datapath.send_msg(flow_mod)
Ejemplo n.º 13
0
    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)
        pkt_arp = pkt.get_protocol(arp.arp)

        dst = eth.dst
        src = eth.src
        dpid = datapath.id
      
        datapath_s2 = api.get_datapath(self,2)
              
        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        
        if eth.ethertype == ether_types.ETH_TYPE_ARP:
            self.logger.info("arp dpid %s", datapath.id)
            if pkt_arp.opcode == arp.ARP_REQUEST:
              dst_ip = pkt_arp.dst_ip
              src_ip = pkt_arp.src_ip
                  
              if dpid == 1:  
               self.arp_reply(datapath, src, '00:00:00:00:00:02', dst_ip, src_ip, eth, msg)   #arp reply to h1
               self.add_entry(datapath, 1, '00:00:00:00:00:02', 2)  #adding entries to switch 1 and 2
               self.add_entry(datapath, 2, '00:00:00:00:00:01', 1)
               self.add_entry(datapath_s2, 1, '00:00:00:00:00:01', 2)
               self.add_entry(datapath_s2, 2, '00:00:00:00:00:02', 1)

              if dpid == 2:
               self.arp_reply(datapath, src, '00:00:00:00:00:01', dst_ip, src_ip, eth, msg)   #arp reply to  h2
Ejemplo n.º 14
0
    def _packet_in_handler(self, ev):
        msg = ev.msg   # ev.msg is an object that represents a packet_in data structure.
        datapath = msg.datapath # msg.datapath is an object that represents a datapath (switch)
        ofproto = datapath.ofproto # datapath.ofproto is an object that represent the OpenFlow protocol that Ryu and the switch negotiated

        pkt = packet.Packet(msg.data)  
        eth = pkt.get_protocol(ethernet.ethernet)
        pkt_arp = pkt.get_protocol(arp.arp)

        dst = eth.dst
        src = eth.src
        dpid = datapath.id #datapath to add the entry to
      
        datapathswitch2 = api.get_datapath(self,2)
        
        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        
        if eth.ethertype == ether_types.ETH_TYPE_ARP:
            if pkt_arp.opcode == arp.ARP_REQUEST:
              dst_ip = pkt_arp.dst_ip
              src_ip = pkt_arp.src_ip

              # ARP spoofing
            
              if dpid == 1:            # ARP reply to host 1      
               self.arp_rep(datapath, src, '00:00:00:00:00:02', dst_ip, src_ip, eth, msg)   
               self.add_ent(datapath, 1, '00:00:00:00:00:02', 2)                            
               self.add_ent(datapath, 2, '00:00:00:00:00:01', 1)
               self.add_ent(datapathswitch2, 1, '00:00:00:00:00:01', 2)
               self.add_ent(datapathswitch2, 2, '00:00:00:00:00:02', 1)

              if dpid == 2:     # ARP reply to host 2
               self.arp_rep(datapath, src, '00:00:00:00:00:01', dst_ip, src_ip, eth, msg)
Ejemplo n.º 15
0
    def _event_switch_enter_handler(self, ev):
        self.logger.info("switch enter: %s", ev.switch.dp.id)
        self.topo.add_node(ev.switch.dp.id)

        datapath = api.get_datapath(self, ev.switch.dp.id)
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        datapath.send_msg(
            ofp_parser.OFPFlowMod(
                datapath,
                command=ofp.OFPFC_ADD,
                match=ofp_parser.OFPMatch(),
                instructions=[
                    ofp_parser.OFPInstructionActions(
                        ofp.OFPIT_APPLY_ACTIONS,
                        actions=[
                            ofp_parser.OFPActionOutput(
                                port=ofp.OFPP_CONTROLLER,
                                max_len=ofp.OFPCML_NO_BUFFER
                            )
                        ]
                    )
                ],
                priority=1
            )
        )
Ejemplo n.º 16
0
    def flow_recreate(self):
        # flow 重建
        for host_mac in self.belong:
            host_port_dpid, host_port_no = self.belong[host_mac]
            self.add_forwaring_rule(
                ofctl_api.get_datapath(self, dpid=host_port_dpid), host_mac,
                host_port_no)

            for dpid in self.res:  # 最短路的计算结果?
                dp = ofctl_api.get_datapath(self, dpid=dpid)

                # 如果是自己 就跳过
                if dpid == host_port_dpid:
                    continue

                # 从图上更新其他switch
                self.add_forwaring_rule(dp, host_mac,
                                        self.res[dpid][host_port_dpid])
 def distribute_single_rule(self, rule):
     for switch in self.connected_switches:
         switch_roles = self.connected_switches[switch]
         if rule.role not in switch_roles:
             continue
         datapath = api.get_datapath(self, switch)
         priority = self.OFP_MAX_PRIORITY
         actions = []
         match = self.create_match(rule)
         self.add_flow(datapath, priority, match, actions)
Ejemplo n.º 18
0
 def apply_rules_for_all(self):
     datapaths = get_datapath(self)
     for datapath in datapaths:
         self.reset_flow_table(datapath)  # install table-miss entry here
         with open(firewall_rule_file) as frfile:
             rules = list(csv.DictReader(frfile))
             priority = len(rules)
             for r in rules:
                 self.apply_rule_for(datapath, r, priority)
                 priority -= 1
 def get_datapath(self, retry_max=cfg.CONF.AGENT.get_datapath_retry_times):
     retry = 0
     while self.datapath is None:
         self.datapath = ryu_api.get_datapath(self.ryuapp, int(self.datapath_id, 16))
         retry += 1
         if retry >= retry_max:
             LOG.error(_LE("Agent terminated!: Failed to get a datapath."))
             raise SystemExit(1)
         time.sleep(1)
     self.set_dp(self.datapath)
Ejemplo n.º 20
0
    def _port_state_change_handler(self, ev):
        #print "EventOFPPortStatus detected"
        msg = ev.msg
        datapath = msg.datapath

        for dpid in self.mac_to_port.keys():
            datapath = api.get_datapath(self, dpid)
            self.del_flow(datapath)
            del self.mac_to_port[dpid]
            self.mac_to_port.setdefault(dpid, {})
Ejemplo n.º 21
0
 def get_datapath(self, retry_max=cfg.CONF.AGENT.get_datapath_retry_times):
     retry = 0
     while self.datapath is None:
         self.datapath = ryu_api.get_datapath(self.ryuapp,
                                              int(self.datapath_id, 16))
         retry += 1
         if retry >= retry_max:
             LOG.error(_('Agent terminated!: Failed to get a datapath.'))
             raise SystemExit(1)
         time.sleep(1)
     self.set_dp(self.datapath)
Ejemplo n.º 22
0
 def _monitor(self):
     while True:
         for dpid in list(self.topo.nodes_iter()):
             datapath = api.get_datapath(self, dpid)
             if datapath is None: continue
             ofp = datapath.ofproto
             ofp_parser = datapath.ofproto_parser
             datapath.send_msg(ofp_parser.OFPPortStatsRequest(
                 datapath, 0, ofp.OFPP_ANY))
             datapath.send_msg(ofp_parser.OFPTableStatsRequest(datapath, 0))
         hub.sleep(self.CONF.dc)
Ejemplo n.º 23
0
    def handle_host_add(self, ev): # 主机上线
        """
        Event handler indiciating a host has joined the network
        This handler is automatically triggered when a host sends an ARP response.
        """
        host = ev.host

        self.logger.warn("Host Added:  %s (IPs:  %s) on switch%s/%s (%s)",
                          host.mac, host.ipv4,
                         host.port.dpid, host.port.port_no, host.port.hw_addr)

        # 1 记录这个主机对应的switch 增加转发表
        # 相当于终端
        self.belong[host.mac] = (host.port.dpid, host.port.port_no)
        self.add_forwaring_rule(
            ofctl_api.get_datapath(self, dpid=host.port.dpid),
            host.mac,
            host.port.port_no
        )

        # 2 更新其他switch上的转发表
        for dpid in self.res: # 最短路的计算结果?
            dp = ofctl_api.get_datapath(self, dpid=dpid)

            # 如果是自己 就跳过
            if dpid == host.port.dpid:
                continue

            # 从图上更新其他switch
            self.add_forwaring_rule(
                dp,
                host.mac,
                self.res[dpid][host.port.dpid]
            )

        # JL: 增加ip-mac对应
        self.ip_mac_dict[host.ipv4[0]] = host.mac

        self.tm.add_host(host)

        print("[BELONG]", self.belong)
Ejemplo n.º 24
0
    def set_config(self, req, **kwargs):
        dpid = dpid_lib.str_to_dpid(kwargs['dpid'])

        try:
            new_config = req.json if req.body else {}
        except ValueError:
            raise Response(status=400)

        if dpid not in self.ctrl.switches:
            self.ctrl.switches[dpid] = SwitchStatus()
        LOG.info("%016x: post %s", dpid, new_config)
        status = self.ctrl.switches[dpid]
        if 'disused' in new_config:
            for p in new_config['disused']:
                LOG.info("%016x: dropping %d", dpid, p)
                status.discard_port(p)
        if 'slices' in new_config:
            for ps in new_config['slices']:
                ps = set(ps)
                LOG.info("%016x: creating %s", dpid, list(ps))
                status.create_slice(ps)
        if 'dhcp' in new_config:
            dp = api.get_datapath(self.ctrl, dpid)
            if new_config['dhcp']:
                self.ctrl.pass_dhcp(dp)
            else:
                self.ctrl.drop_dhcp(dp)
        status.revalidate()
        LOG.info("%016x: completed changes", dpid)
        if 'learn' in new_config:
            dp = api.get_datapath(self.ctrl, dpid)
            mac = new_config['learn']['mac']
            port = new_config['learn']['port']
            timeout = new_config['learn']['timeout'] \
                      if 'timeout' in new_config['learn'] \
                         else 600
            self.ctrl._learn(dp, port, mac, timeout=timeout);

        body = json.dumps(status.get_config()) + "\n"
        return Response(content_type='application/json', body=body)
Ejemplo n.º 25
0
    def forward_frame(self, dpid, out_port, frame):
        datapath = ofctl_api.get_datapath(self, dpid=dpid)
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        match = parser.OFPMatch(in_port=ofproto.OFPP_ANY)
        actions = [parser.OFPActionOutput(out_port)]
        out = parser.OFPPacketOut(datapath=datapath,
                                  match=match,
                                  actions=actions,
                                  data=bytes(frame))

        datapath.send_msg(out)
 def switch_role_assign(self, switch_id, new_role):
     if new_role not in self.role_to_rules:
         return (False, "Role " + new_role + " does not exist.")
     if switch_id not in self.connected_switches:
         return (False, "Switch " + str(switch_id) + " does not exist.")
     if new_role in self.connected_switches[switch_id]:
         return (False, "Switch " + str(switch_id) + " already has role "
                 + str(new_role) + ".")
     self.connected_switches[switch_id].append(new_role)
     datapath = api.get_datapath(self, switch_id)
     self.distribute_rules_role_set(datapath, new_role)
     print("[+] Switch " + str(switch_id) + " assigned role: " + new_role)
     return (True, "Switch " + str(switch_id) + " given role "
             + new_role + ".")
Ejemplo n.º 27
0
    def _send(self, dpid, msg):
        datapath = api.get_datapath(self, dpid)
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        if isinstance(msg, ofp_parser.OFPFlowMod):
            k = (dpid, msg.match['in_port'])
            self.count_arrv[k] = 1 + self.count_arrv.get(k, 0)
            if k in self.evports:
                dlport = self.evports[k]
                for _,odpid,(ipt,opt) in (
                    self.topo.out_edges_iter(dpid, data='pt')):
                    if ipt == dlport:
                        dlport = None
                        rewrite_msg(datapath, msg, opt)
                        dpid = odpid
                        break
                assert dlport is None
        elif isinstance(msg, ofp_parser.OFPPacketOut):
            if self.rewrite is not None:
                dpid, export = self.rewrite
                rewrite_msg(datapath, msg, export)
        api.get_datapath(self, dpid).send_msg(msg)
 def policy_switch_assign(self, switch_id, new_policy):
     if new_policy not in self._policy_to_rules:
         return (False, "Policy " + new_policy + " does not exist.")
     if switch_id not in self._connected_switches:
         return (False, "Switch " + str(switch_id) + " does not exist.")
     if new_policy in self._connected_switches[switch_id]:
         return (False, "Switch " + str(switch_id) + " already has policy "
                 + str(new_policy) + ".")
     self._connected_switches[switch_id].append(new_policy)
     datapath = api.get_datapath(self, switch_id)
     self._distribute_rules_policy_set(datapath, new_policy)
     print("[+] Switch " + str(switch_id) + " assigned policy: " + new_policy)
     return (True, "Switch " + str(switch_id) + " given policy "
             + new_policy + ".")
Ejemplo n.º 29
0
 def policy_switch_assign(self, switch_id, new_policy):
     if new_policy not in self._policy_to_rules:
         return (False, "Policy " + new_policy + " does not exist.")
     if switch_id not in self._connected_switches:
         return (False, "Switch " + str(switch_id) + " does not exist.")
     if new_policy in self._connected_switches[switch_id]:
         return (False, "Switch " + str(switch_id) +
                 " already has policy " + str(new_policy) + ".")
     self._connected_switches[switch_id].append(new_policy)
     datapath = api.get_datapath(self, switch_id)
     self._distribute_rules_policy_set(datapath, new_policy)
     print("[+] Switch " + str(switch_id) + " assigned policy: " +
           new_policy)
     return (True, "Switch " + str(switch_id) + " given policy " +
             new_policy + ".")
 def delete_acl_rule(self, rule_id):
     if rule_id not in self.access_control_list:
         return (False, "Invalid rule id given: " + rule_id + ".")
     # The user passed through a valid rule_id so we can proceed
     rule = self.access_control_list[rule_id]
     del self.access_control_list[rule_id]
     self.role_to_rules[rule.role].remove(rule_id)
     for switch in self.connected_switches:
         if rule.role not in self.connected_switches[switch]:
             continue
         match = self.create_match(rule)
         datapath = api.get_datapath(self, switch)
         self.delete_flow(datapath, self.OFP_MAX_PRIORITY, match)
     print("[+] Rule " + str(rule) + " with id: " + str(rule_id)
           + " removed.")
     return (True, "Rule with id \'" + rule_id + "\' was deleted.")
 def _distribute_single_rule(self, rule):
     for switch in self._connected_switches:
         switch_policies = self._connected_switches[switch]
         if rule.policy not in switch_policies:
             continue
         datapath = api.get_datapath(self, switch)
         priority = self.OFP_MAX_PRIORITY
         actions = []
         match = self._create_match(rule)
         if rule.time_duration == "N/A":
             self._add_flow(datapath, priority, match, actions,
                            table_id=self.TABLE_ID_ACL)
         else:
             self._add_flow(datapath, priority, match, actions,
                           time_limit=(int(rule.time_duration)),
                           table_id=self.TABLE_ID_ACL)
Ejemplo n.º 32
0
    def flow_reset(self):
        # flow 清空
        for switch in self.switch_list:
            datapath = ofctl_api.get_datapath(self, dpid=switch.dp.id)
            empty_match = datapath.ofproto_parser.OFPMatch()
            cmd = datapath.ofproto.OFPFC_DELETE
            actions = []

            ofp_parser = datapath.ofproto_parser

            flow_mod = datapath.ofproto_parser.OFPFlowMod(datapath,
                                                          match=empty_match,
                                                          cookie=0,
                                                          command=cmd,
                                                          priority=65535,
                                                          actions=actions)
            datapath.send_msg(flow_mod)
 def switch_role_remove(self, switch_id, old_role):
     if old_role not in self.role_to_rules:
         return (False, "Role " + old_role + " does not exist.")
     if switch_id not in self.connected_switches:
         return (False, "Switch " + str(switch_id) + " does not exist.")
     if old_role not in self.connected_switches[switch_id]:
         return (False, "Switch " + str(switch_id) + " does not have role "
                 + str(old_role) + ".")
     self.connected_switches[switch_id].remove(old_role)
     datapath = api.get_datapath(self, switch_id)
     for rule_id in self.role_to_rules[old_role]:
         rule = self.access_control_list[rule_id]
         match = self.create_match(rule)
         self.delete_flow(datapath, self.OFP_MAX_PRIORITY, match)
     print("[+] Switch " + str(switch_id) + " removed role: " + old_role)
     return (True, "Switch " + str(switch_id) + " had role "
             + old_role + " removed.")
Ejemplo n.º 34
0
 def _get_dp_by_dpid(self, dpid_int):
     """Get Ryu datapath object for the switch."""
     timeout_sec = cfg.CONF.OVS.of_connect_timeout
     start_time = timeutils.now()
     while True:
         dp = ofctl_api.get_datapath(self._app, dpid_int)
         if dp is not None:
             break
         # The switch has not established a connection to us.
         # Wait for a little.
         if timeutils.now() > start_time + timeout_sec:
             m = _("Switch connection timeout")
             LOG.error(m)
             # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
             raise RuntimeError(m)
         eventlet.sleep(1)
     return dp
Ejemplo n.º 35
0
 def _get_dp_by_dpid(self, dpid_int):
     """Get Ryu datapath object for the switch."""
     timeout_sec = cfg.CONF.OVS.of_connect_timeout
     start_time = timeutils.now()
     while True:
         dp = ofctl_api.get_datapath(self._app, dpid_int)
         if dp is not None:
             break
         # The switch has not established a connection to us.
         # Wait for a little.
         if timeutils.now() > start_time + timeout_sec:
             m = _("Switch connection timeout")
             LOG.error(m)
             # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
             raise RuntimeError(m)
         eventlet.sleep(1)
     return dp
 def policy_switch_remove(self, switch_id, old_policy):
     if old_policy not in self._policy_to_rules:
         return (False, "policy " + old_policy + " does not exist.")
     if switch_id not in self._connected_switches:
         return (False, "Switch " + str(switch_id) + " does not exist.")
     if old_policy not in self._connected_switches[switch_id]:
         return (False, "Switch " + str(switch_id) + " does not have policy "
                 + str(old_policy) + ".")
     self._connected_switches[switch_id].remove(old_policy)
     datapath = api.get_datapath(self, switch_id)
     for rule_id in self._policy_to_rules[old_policy]:
         rule = self._access_control_list[rule_id]
         match = self._create_match(rule)
         self._delete_flow(datapath, self.OFP_MAX_PRIORITY, match)
     print("[+] Switch " + str(switch_id) + " removed policy: " + old_policy)
     return (True, "Switch " + str(switch_id) + " had policy "
             + old_policy + " removed.")
Ejemplo n.º 37
0
 def policy_switch_remove(self, switch_id, old_policy):
     if old_policy not in self._policy_to_rules:
         return (False, "policy " + old_policy + " does not exist.")
     if switch_id not in self._connected_switches:
         return (False, "Switch " + str(switch_id) + " does not " "exist.")
     if old_policy not in self._connected_switches[switch_id]:
         return (False, "Switch " + str(switch_id) + " does not have "
                 "policy " + str(old_policy) + ".")
     self._connected_switches[switch_id].remove(old_policy)
     datapath = api.get_datapath(self, switch_id)
     for rule_id in self._policy_to_rules[old_policy]:
         rule = self._access_control_list[rule_id]
         match = self._create_match(rule)
         self._delete_flow(datapath, self.OFP_MAX_PRIORITY, match)
     print("[+] Switch " + str(switch_id) + " removed policy: " +
           old_policy)
     return (True, "Switch " + str(switch_id) + " had policy " +
             old_policy + " removed.")
 def clean_flows(self):
     dps = api.get_datapath(self)
     for dp in dps:
         ofp = dp.ofproto
         parser = dp.ofproto_parser
         match = parser.OFPMatch()
         # Delete all flows
         instructions = []
         flow_mod = parser.OFPFlowMod(dp, 0, 0, 0, ofp.OFPFC_DELETE, 0, 0,
                                      1, ofp.OFPCML_NO_BUFFER, ofp.OFPP_ANY,
                                      OFPG_ANY, 0, match, instructions)
         dp.send_msg(flow_mod)
         # Install the table-miss flow entry
         actions = [
             parser.OFPActionOutput(ofp.OFPP_CONTROLLER,
                                    ofp.OFPCML_NO_BUFFER)
         ]
         self.add_flow(dp, 0, match, actions)
     del self.packet_log[:]
Ejemplo n.º 39
0
 def port_status_handler(self, ev):
     msg = ev.msg
     dp = msg.datapath
     ofp = dp.ofproto
     ofp_parser = dp.ofproto_parser
     swid = dp.id
     port = msg.desc
     
     if port.state == ofp.OFPPS_LINK_DOWN:
         # 1.2 : host removed from network; update mac table
         bad_MAC = self.get_MAC(self.MAC_table[swid], port.port_no)
         if bad_MAC != None:
             self.MAC_table[swid].pop(bad_MAC)
             print('Removed from MAC table: MAC: {}'.format(bad_MAC))
         
         # 1.3: all flow entries related to that host should be removed;
         match = ofp_parser.OFPMatch(eth_dst=bad_MAC)
         dp_list = get_datapath(self, None)
         for dp_item in dp_list:
             self.remove_flow(dp_item, match)
Ejemplo n.º 40
0
    def acl_rule_delete(self, rule_id):
        if rule_id not in self._access_control_list:
            return (False, "Invalid rule id given: " + rule_id + ".")
        # The user passed through a valid rule_id so we can proceed
        rule = self._access_control_list[rule_id]
        del self._access_control_list[rule_id]
        self._policy_to_rules[rule.policy].remove(rule_id)
        # The rule had time enforcement, it must be removed from the queue
        if rule.time_start != "N/A":
            self._remove_from_queue(rule_id)

        # Send off delete flow messages to switches that hold the rule
        for switch in self._connected_switches:
            if rule.policy not in self._connected_switches[switch]:
                continue
            match = self._create_match(rule)
            datapath = api.get_datapath(self, switch)
            self._delete_flow(datapath, self.OFP_MAX_PRIORITY, match, rule.dst_list)
        print("[+] Rule " + str(rule) + " with id: " + str(rule_id)
              + " removed.")
        return (True, "Rule with id \'" + rule_id + "\' was deleted.")
Ejemplo n.º 41
0
    def acl_rule_delete(self, rule_id):
        if rule_id not in self._access_control_list:
            return (False, "Invalid rule id given: " + rule_id + ".")
        # The user passed through a valid rule_id so we can proceed
        rule = self._access_control_list[rule_id]
        del self._access_control_list[rule_id]
        self._policy_to_rules[rule.policy].remove(rule_id)
        # The rule had time enforcement, it must be removed from the
        # queue.
        if rule.time_start != "N/A":
            self._remove_from_queue(rule_id)

        # Send off delete flow messages to switches that hold the rule
        for switch in self._connected_switches:
            if rule.policy not in self._connected_switches[switch]:
                continue
            match = self._create_match(rule)
            datapath = api.get_datapath(self, switch)
            self._delete_flow(datapath, self.OFP_MAX_PRIORITY, match)
        print("[+] Rule " + str(rule) + " with id: " + str(rule_id) +
              " removed.")
        return (True, "Rule with id \'" + rule_id + "\' was deleted.")
Ejemplo n.º 42
0
 def _distribute_single_rule(self, rule):
     for switch in self._connected_switches:
         switch_policies = self._connected_switches[switch]
         if rule.policy not in switch_policies:
             continue
         datapath = api.get_datapath(self, switch)
         priority = self.OFP_MAX_PRIORITY
         actions = []
         match = self._create_match(rule)
         if rule.time_duration == "N/A":
             self._add_flow(datapath,
                            priority,
                            match,
                            actions,
                            table_id=self.TABLE_ID_ACL)
         else:
             self._add_flow(datapath,
                            priority,
                            match,
                            actions,
                            time_limit=(int(rule.time_duration)),
                            table_id=self.TABLE_ID_ACL)
Ejemplo n.º 43
0
	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)
        
		pkt_arp = pkt.get_protocol(arp.arp)


        

		dst = eth.dst
        
		src = eth.src
        
		dpid = datapath.id
      
        
	
		datapath_s2 = api.get_datapath(self,2)
        
		datapath_s1 = api.get_datapath(self,1)

        

        

		if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            
			# ignore lldp packet
            
			return
        
        

		if eth.ethertype == ether_types.ETH_TYPE_ARP:
            
			self.logger.info("arp dpid %s", datapath.id)
            
			if pkt_arp.opcode == arp.ARP_REQUEST and dpid == 1:
              
				dst_ip = pkt_arp.dst_ip
              
				src_ip = pkt_arp.src_ip

              
				self.logger.info("%s sends arp request to %s through %s with opcode %s in port %s", src_ip, dst_ip, dpid, pkt_arp.opcode, msg.in_port) 
              
              
	
				self.arp_reply(datapath, src, '00:00:00:00:00:02', dst_ip, src_ip, eth, msg)
                  
          
              
				#2 entries for switch 1
              
				self.add_entry(datapath, 1, '10.0.0.1','10.0.0.2', 2, eth)
   
           			self.add_entry(datapath, 2, '10.0.0.2','10.0.0.1', 1, eth)
               
              
			
				#2 entries for switch 2
              
				datapath = datapath_s2
              
				self.add_entry(datapath, 1, '10.0.0.2','10.0.0.1', 2, eth)
              
				self.add_entry(datapath, 2, '10.0.0.1','10.0.0.2', 1, eth)

            

			if pkt_arp.opcode == arp.ARP_REQUEST and dpid == 2:
              
				dst_ip = pkt_arp.dst_ip
              
				src_ip = pkt_arp.src_ip

              
				self.logger.info("%s sends arp request to %s through %s with opcode %s in port %s", src_ip, dst_ip, dpid, pkt_arp.opcode, msg.in_port)

 
             
				self.arp_reply(datapath_s2, src, '00:00:00:00:00:01', dst_ip, src_ip, eth, msg)

     
              

				#2 entries for switch 2
              
				self.add_entry(datapath, 1, '10.0.0.2','10.0.0.1', 2, eth)
              
				self.add_entry(datapath, 2, '10.0.0.1','10.0.0.2', 1, eth)


              

				#2 entries for switch 1
              
				datapath = datapath_s1
              
				self.add_entry(datapath, 1, '10.0.0.1','10.0.0.2', 2, eth)
              
				self.add_entry(datapath, 2, '10.0.0.2','10.0.0.1', 1, eth)
Ejemplo n.º 44
0
    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']
 
        pkt = packet.Packet(msg.data)

        #Get protocols
        eth = pkt.get_protocol(ethernet.ethernet)
        ip = pkt.get_protocol(ipv4.ipv4)
        p_arp = pkt.get_protocol(arp.arp)

        #Ignore LLDP packets
        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            return
        
        dst = eth.dst
        src = eth.src
        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        if src not in self.net:
            self.net.add_node(src)
            self.net.add_edge(dpid,src,port=in_port)
            self.net.add_edge(src,dpid)

        if p_arp:
            ipv4_src = ip.src if ip != None else p_arp.src_ip
            ipv4_dst = ip.dst if ip != None else p_arp.dst_ip
            target_mac = ip_to_mac[ipv4_dst]
            print "ARP!", ipv4_src, ipv4_dst
            self.send_arp(datapath, arp.ARP_REPLY, target_mac ,src, ipv4_dst, ipv4_src,src, ofproto.OFPP_CONTROLLER, in_port)
            return
       
        if dst in self.net:

            if ip != None and ip.dst in SFCs.keys():
                if (ip.dst,ip.src) in SFC_flows.keys():
                    #print "Reflowing: DPID", dpid, ":", in_port, " ", ip.src, "->", ip.dst 
                    #print PoPs
                    #print SFC_flows 
                    return
                    #self.remove_flow(SFC_flows[(ip.dst,ip.src)])
                else:
                    SFC_flows[(ip.dst,ip.src)] = self.flow_id
                path_source = src
                whole_path = SFCs[ip.dst]
                whole_path.append(ip.dst)

                for pop in whole_path:
                    if pop == ip.dst:
                        path_target = ip_to_mac[pop]
                    else:
                        path_target = ip_to_mac[self.select_closest_pop(pop,self.flow_id,src)]
                    try:
                        path=nx.shortest_path(self.net,path_source,path_target)  
                    except nx.NetworkXError:
                        print "NX Error:"
                        print nx.edges()
                    first = True
                    for i in path:
                        if isinstance(i,int):
                            switchDP = api.get_datapath(self, i)
                            next = path[path.index(i)+1]
                            pathes=self.net[i][next]
                            out_port=[pathes[p]['port'] for p in pathes if 'port' in pathes[p]][0]
                            actions = []
                            if first:
                                first = False
                                if path_source == src:
                                    paths=self.net[i][src] #may not work for multiple connections between 2 switches
                                    in_port=[paths[p]['port'] for p in paths if 'port' in paths[p]][0]
                                    #print "Src switch:", switchDP
                                    first_packet_actions = [datapath.ofproto_parser.OFPActionSetField(ip_dscp=1), datapath.ofproto_parser.OFPActionOutput(out_port) ]
                                    actions.append(switchDP.ofproto_parser.OFPActionSetField(ip_dscp=1))
                                    match = switchDP.ofproto_parser.OFPMatch(eth_type=0x800,in_port=in_port, ipv4_src=ip.src,ipv4_dst=ip.dst)
                                else:
                                    match = switchDP.ofproto_parser.OFPMatch(eth_type=0x800,in_port=2, ipv4_src=ip.src,ipv4_dst=ip.dst)#Later match for dscp
                                    #match correct in_port 
                            else:
                                match = switchDP.ofproto_parser.OFPMatch(eth_type=0x800,in_port=in_port, ipv4_src=ip.src,ipv4_dst=ip.dst)#Later match for dscp
                            actions.append(switchDP.ofproto_parser.OFPActionOutput(out_port))
                            self.add_flow(switchDP, match, actions, 2049,self.flow_id)
                            if next != path_target: #Last of segment
                                paths=self.net[next][i] #may not work for multiple connections between 2 switches
                                in_port=[paths[p]['port'] for p in paths if 'port' in paths[p]][0]
                            #if next != dst: #Last of All
                            #    #add_flow
                            #else
                            #    #add_flow
                    path_source = path_target
                #print SFC_flows[(ip.dst,ip.src)]


                self.flow_id+=1
                if self.flow_id >= 254:
                    self.flow_id=1
    
                out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,actions=first_packet_actions, data=msg.data)
                datapath.send_msg(out)

                return
            else:
                #Local hop mac redirection (non-SFC traffic)
                path=nx.shortest_path(self.net,src,dst)  
                next=path[path.index(dpid)+1]
                paths=self.net[dpid][next]
                out_port=[paths[p]['port'] for p in paths if 'port' in paths[p]][0]

                match = datapath.ofproto_parser.OFPMatch(eth_type=0x800,in_port=in_port, eth_dst=dst)
                actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
                self.add_flow(datapath, match, actions,2048,0)

                #Clausula de ataque:
                if next == dst and in_port == 2 and "01:0" in dst:
                    print "Ataque: ", dst
                    actions.append(datapath.ofproto_parser.OFPActionOutput(out_port))
                #Fim da clausula de ataque


                #print "b", src, "->", dst
                #print "  path: ", path
                #print "  outport: ", out_port
                #print "  next: ", next
                #print "  dpid: ", dpid
                #print self.net.edges(data=True, keys=True)
                out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,actions=actions, data=msg.data)

                datapath.send_msg(out)
Ejemplo n.º 45
0
    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']
 
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)
 
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        #p_arp = self._find_protocol(pkt, "arp")

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
	   # print "lldp"
            # ignore lldp packet
            return

        ip = pkt.get_protocol(ipv4.ipv4)

        dst = eth.dst
        src = eth.src
        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})
        #print "nodes"
        #print self.net.nodes()
        #print "edges"
        #print self.net.edges()


        p_arp = pkt.get_protocol(arp.arp)
        if p_arp:
            ipv4_src = ip.src if ip != None else p_arp.src_ip
            ipv4_dst = ip.dst if ip != None else p_arp.dst_ip
            target_mac = ip_to_mac[ipv4_dst]
            print "ARP!", ipv4_src, ipv4_dst
            self.send_arp(datapath, arp.ARP_REPLY, target_mac ,src, ipv4_dst, ipv4_src,src, ofproto.OFPP_CONTROLLER, in_port)
            return
       
            
        if src not in self.net:
            #print "1 Src:", src
            self.net.add_node(src)
            self.net.add_edge(dpid,src,port=in_port)
            self.net.add_edge(src,dpid)
        if dst in self.net:
            #print "2"
            if dst in SFCs.keys() and ip != None:
                #path=(nx.shortest_path(self.net,src,SFCs[dst]), nx.shortest_path(self.net,SFCs[dst],dst))  
                #Tag the flow!
                #if dpid == 3:
                #    if in_port == 2:
                #actions = [
                #           datapath.ofproto_parser.OFPActionSetField(ip_dscp=0),
                #           datapath.ofproto_parser.OFPActionOutput(out_port)
                #          ]
                #self.add_sfc_flow(datapath, in_port, dst, actions,0)
                #if dpid == 3:
                #    actions = [
                #               datapath.ofproto_parser.OFPActionSetField(ip_dscp=1),
                #               datapath.ofproto_parser.OFPActionOutput(out_port)
                #              ]
                #    self.add_sfc_flow(datapath, in_port, dst, actions,0)

                #actions = [
                #           datapath.ofproto_parser.OFPActionSetField(ip_dscp=0),
                #           datapath.ofproto_parser.OFPActionOutput(out_port)
                #          ]
                #self.add_flow(datapath, in_port, dst, actions)
                

                path=nx.shortest_path(self.net,src,SFCs[dst])  
                print path
                for i in path:
                    if isinstance(i,int):
                        switchDP = api.get_datapath(self, i)
                        #switchId = switchDP.id
                        next = path[path.index(i)+1]
                        pathes=self.net[i][next]
                        out_port=[pathes[p]['port'] for p in pathes if 'port' in pathes[p]][0]
                        #out_port = self.net[i][next][0]['port']
                        print i, out_port, next
                        if i == dpid:
                            print "First"
                            actions = [
                                       switchDP.ofproto_parser.OFPActionSetField(ip_dscp=0),
                                       switchDP.ofproto_parser.OFPActionOutput(out_port)
                                      ]
                            self.add_first_flow(datapath,in_port, dst, actions)
                            out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,actions=actions, data=msg.data)
                        elif next == SFCs[dst]:
                            print "next"
                            actions = [
                                switchDP.ofproto_parser.OFPActionSetField(ip_dscp=1),
                                switchDP.ofproto_parser.OFPActionOutput(1)
                                      ]
                            self.add_sfc_pop_flow(switchDP, 3, dst, actions,0)

                        else:
                            actions = [
                                       #switchDP.ofproto_parser.OFPActionSetField(ip_dscp=0),
                                       switchDP.ofproto_parser.OFPActionOutput(out_port)
                                      ]
                            self.add_sfc_flow(switchDP, dst, actions,0)
                            
                        last = i

                print "POP: ", last
                actions = [
                           switchDP.ofproto_parser.OFPActionSetField(ip_dscp=1),
                           switchDP.ofproto_parser.OFPActionOutput(4)
                          ]
                self.add_sfc_pop_flow(switchDP, 2, dst, actions,1)
                

                path=nx.shortest_path(self.net,SFCs[dst],dst)  
                #path=nx.shortest_path(self.net,src,dst)  
                for i in path:
                    if isinstance(i,int) and i != last:
                        switchDP = api.get_datapath(self, i)
                        #switchId = switchDP.id
                        next = path[path.index(i)+1]
                        pathes=self.net[i][next]
                        out_port=[pathes[p]['port'] for p in pathes if 'port' in pathes[p]][0]
                        #out_port = self.net[i][next][0]['port']
                        print i, out_port, next
                        if next == dst:
                            actions = [
                                       switchDP.ofproto_parser.OFPActionSetField(ip_dscp=0),
                                       switchDP.ofproto_parser.OFPActionOutput(out_port)
                                      ]
                            self.add_sfc_flow(switchDP, dst, actions,1)
                        else:
                            actions = [
                                       switchDP.ofproto_parser.OFPActionOutput(out_port)
                                      ]
                            self.add_sfc_flow(switchDP, dst, actions,1)
                        #self.add_flow_debug(switchDP, dst, actions)
                datapath.send_msg(out)
                return
            else:
                print "b:", dst 
                path=nx.shortest_path(self.net,src,dst)  
                next=path[path.index(dpid)+1]
                pathes=self.net[dpid][next]
                out_port=[pathes[p]['port'] for p in pathes if 'port' in pathes[p]][0]
                #out_port=self.net[dpid][next][0]['port']
            #path=nx.shortest_path(self.net,src,'00:00:00:00:00:03')  
                actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
                self.add_flow(datapath, in_port, dst, actions)

            print "  path: ", path
            print "  outport: ", out_port
            print "  next: ", next
            print "  dpid: ", dpid
            #print self.net.edges(data=True, keys=True)
        else:
            #print "3"
            out_port = ofproto.OFPP_FLOOD
            return
 
        # install a flow to avoid packet_in next time
        #if out_port != ofproto.OFPP_FLOOD:
        #    self.add_flow(datapath, in_port, dst, actions)
 
        out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,actions=actions, data=msg.data)

        datapath.send_msg(out)