Пример #1
0
 def forward_packet(self, in_port, out_port, data):
     actions = [OFPActionOutput(out_port)]
     out = OFPPacketOut(datapath=self.dp,
                        buffer_id=ofproto_v1_3.OFP_NO_BUFFER,
                        in_port=in_port, actions=actions,
                        data=data)
     self.dp.send_msg(out)
Пример #2
0
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath

        # install the table-miss flow entry.
        match = OFPMatch()
        actions = [OFPActionOutput(ofproto_v1_3.OFPP_CONTROLLER,
                                   ofproto_v1_3.OFPCML_NO_BUFFER)]
        self.add_flow(datapath, 0, match, actions)
Пример #3
0
    def handle(self, in_port, data):
        pkt = packet.Packet(data)
        eth_pkt = pkt.get_protocol(ethernet.ethernet)

        ports = self.get_forwarding_ports(in_port, eth_pkt)
        self.forward_packet(in_port, ports[0], data)

        for port in ports:
            match = OFPMatch(in_port=in_port, eth_dst=eth_pkt.dst)
            actions = [OFPActionOutput(port)]
            self.add_flow(10, match, actions)
            print 'add flow for %s from port %s to %s' % (self.dp.id,in_port, port)
Пример #4
0
    def handle(self, in_port, data):
        pkt = packet.Packet(data)
        eth_pkt = pkt.get_protocol(ethernet.ethernet)

        self.host_table[eth_pkt.src] = in_port

        if eth_pkt.dst in self.host_table:
            port = self.host_table[eth_pkt.dst]
            match = OFPMatch(in_port=in_port, eth_dst=eth_pkt.dst)
            actions = [OFPActionOutput(port)]
            self.add_flow(10, match, actions)
            self.forward_packet(in_port, port, data)
        else:
            self.forward_packet(in_port, ofproto_v1_3.OFPP_FLOOD, data)
Пример #5
0
    def test_convert_instructions(self):
        """ Test converting instructions from ryu """
        ryu_inst = [OFPInstructionWriteMetadata(0x56, 0xff)]
        inst = Instructions()
        inst.write_metadata = (0x56, 0xff)
        self.assertEqual(instructions_from_ryu(ryu_inst), inst)

        ryu_inst = [OFPInstructionGotoTable(6)]
        inst = Instructions()
        inst.goto_table = 6
        self.assertEqual(instructions_from_ryu(ryu_inst), inst)

        output = OFPActionOutput(1)
        ryu_inst = [OFPInstructionActions(OFPIT_APPLY_ACTIONS, [output])]
        inst = Instructions()
        inst.apply_actions = ActionList([('OUTPUT', 1)])
        self.assertEqual(instructions_from_ryu(ryu_inst), inst)

        output = OFPActionOutput(2)
        ryu_inst = [OFPInstructionActions(OFPIT_WRITE_ACTIONS, [output])]
        inst = Instructions()
        inst.write_actions = ActionSet([('OUTPUT', 2)])
        self.assertEqual(instructions_from_ryu(ryu_inst), inst)
Пример #6
0
    def _handle_switch_features(self, event):
        """
        Installs the default flow rule for every switch that connects
        to the controller
        :param event: The SwitchFeatures event
        :type event: EventOFPSwitchFeatures
        :return: None
        :rtype: None
        """
        datapath = event.msg.datapath
        self.logger.debug("[S{}] SwitchFeatures Event".format(datapath.id))
        self.switches[datapath.id] = datapath

        self.program_flow(datapath, OFPMatch(),
                          [OFPActionOutput(OFPP_CONTROLLER)], 0, 0, 0)
        datapath.send_msg(OFPSetConfig(datapath, OFPC_FRAG_NORMAL, 0xffff))
        self.handle_switch_features(event)
Пример #7
0
    def test_convert_flow(self):
        """ Test converting OFPFlowMod and OFPFlowStats from ryu """
        ryu_match = OFPMatch(ipv4_src=1, eth_type=0x8100, vlan_vid=0x1100)
        ryu_write_actions = OFPInstructionActions(OFPIT_WRITE_ACTIONS, [
            OFPActionPopVlan(),
            OFPActionSetField(eth_dst="10:10:10:10:10:10"),
            OFPActionOutput(7)
        ])
        ryu_instructions = [
            OFPInstructionActions(OFPIT_CLEAR_ACTIONS, []), ryu_write_actions,
            OFPInstructionGotoTable(9),
            OFPInstructionWriteMetadata(0x99, 0xff)
        ]
        ryu_flow_mod = OFPFlowMod(datapath=None,
                                  cookie=0xABCD,
                                  table_id=3,
                                  command=OFPFC_ADD,
                                  priority=789,
                                  match=ryu_match,
                                  instructions=ryu_instructions)
        ryu_flow_stats = OFPFlowStats(cookie=0xABCD,
                                      table_id=3,
                                      priority=789,
                                      match=ryu_match,
                                      instructions=ryu_instructions)

        match = Match([("IPV4_SRC", 1, None), ("ETH_TYPE", 0x8100, None),
                       ("VLAN_VID", 0x1100, None)])
        instructions = Instructions()
        instructions.goto_table = 9
        instructions.clear_actions = True
        instructions.write_actions.append("POP_VLAN", None)
        instructions.write_actions.append("SET_FIELD",
                                          ("ETH_DST", 0x101010101010))
        instructions.write_actions.append("OUTPUT", 7)
        instructions.write_metadata = (0x99, 0xff)

        rule = Rule(priority=789,
                    cookie=0xABCD,
                    table=3,
                    match=match,
                    instructions=instructions)

        self.assertEqual(rule_from_ryu(ryu_flow_stats), rule)
        self.assertEqual(rule_from_ryu(ryu_flow_mod), rule)
Пример #8
0
 def send_pkt(self, datapath, data, port=OFPP_FLOOD):
     """
     Convenience method that instructs a switch to forward
     a packet from the controller.
     :param datapath: The datapath to the switch from which to send
     :type datapath: Datapath
     :param data: The data to forward
     :type data:
     :param port: The port on which to forward
     :type port: int
     """
     self.logger.debug("[S{}] Forwarding packet on port {}".format(
         datapath.id, port))
     out = OFPPacketOut(datapath=datapath,
                        actions=[OFPActionOutput(port)],
                        in_port=OFPP_CONTROLLER,
                        data=data,
                        buffer_id=OFP_NO_BUFFER)
     datapath.send_msg(out)
Пример #9
0
    def handle_packet_in(self, event):
        """
        Installs flow rules for incoming packets using Dijkstra
        :param event: The PacketIn event
        :type event: EventOFPPacketIn
        :return: Any generated flow IDs
        :rtype: list
        """
        message = event.msg
        datapath = message.datapath
        switch_id = datapath.id
        packet = Packet(message.data)
        ipv4_info = packet.get_protocol(ipv4)
        if ipv4_info is None:
            return []

        out_port, src_subnet, dst_subnet = \
            self.routing_algo.calculate_routing_decision(
                switch_id, ipv4_info.src, ipv4_info.dst
            )
        match = OFPMatch(eth_type=ether_types.ETH_TYPE_IP,
                         ipv4_src=src_subnet,
                         ipv4_dst=dst_subnet)

        # If packets come in very quickly, the flow rule may not be installed
        # yet. To avoid creating new flows, we check if the flow rules were
        # already registered in active_flows.
        for existing_flow in self.active_flows.values():
            if existing_flow.is_ipv4_match_equal(switch_id, match):
                self.send_pkt(datapath, message.data, out_port)
                return []

        actions = [OFPActionOutput(out_port)]
        flow_id = self.program_flow(datapath=datapath,
                                    match=match,
                                    actions=actions,
                                    priority=10,
                                    hard_timeout=120,
                                    idle_timeout=5)
        self.send_pkt(datapath, message.data, out_port)
        return [flow_id]
Пример #10
0
    def test_convert_actions(self):
        """ Test all action conversions work correctly """

        # First check set returns a set
        self.assertIs(type(actions_from_ryu([OFPActionOutput(6)], 'set')),
                      ActionSet)
        # And list a list
        self.assertIs(type(actions_from_ryu([OFPActionOutput(6)], 'list')),
                      ActionList)

        # Now check all the action types, OUTPUT etc
        self.assertEqual(actions_from_ryu([OFPActionOutput(6)], 'list'),
                         ActionList([('OUTPUT', 6)]))
        self.assertEqual(actions_from_ryu([OFPActionGroup(7)], 'list'),
                         ActionList([('GROUP', 7)]))
        self.assertEqual(actions_from_ryu([OFPActionSetQueue(8)], 'list'),
                         ActionList([('SET_QUEUE', 8)]))
        # Push/Pop
        self.assertEqual(actions_from_ryu([OFPActionPushVlan(0x8100)], 'list'),
                         ActionList([('PUSH_VLAN', 0x8100)]))
        self.assertEqual(actions_from_ryu([OFPActionPushVlan(0x88a8)], 'list'),
                         ActionList([('PUSH_VLAN', 0x88a8)]))
        self.assertEqual(actions_from_ryu([OFPActionPopVlan()], 'list'),
                         ActionList([('POP_VLAN', None)]))
        self.assertEqual(actions_from_ryu([OFPActionPushMpls(0x8847)], 'list'),
                         ActionList([('PUSH_MPLS', 0x8847)]))
        self.assertEqual(actions_from_ryu([OFPActionPushMpls(0x8848)], 'list'),
                         ActionList([('PUSH_MPLS', 0x8848)]))
        self.assertEqual(actions_from_ryu([OFPActionPopMpls(0x0800)], 'list'),
                         ActionList([('POP_MPLS', 0x0800)]))
        self.assertEqual(actions_from_ryu([OFPActionPushPbb(0x88e7)], 'list'),
                         ActionList([('PUSH_PBB', 0x88e7)]))
        self.assertEqual(actions_from_ryu([OFPActionPopPbb()], 'list'),
                         ActionList([('POP_PBB', None)]))

        # SET_FIELD, take this chance to check we can do MAC, IPv4/6 conversion
        # as ryu might be using those.
        set_field = OFPActionSetField(vlan_vid=100)
        self.assertEqual(actions_from_ryu([set_field], 'list'),
                         ActionList([("SET_FIELD", ('VLAN_VID', 100))]))
        set_field = OFPActionSetField(eth_dst="10:11:12:13:14:15")
        self.assertEqual(
            actions_from_ryu([set_field], 'list'),
            ActionList([("SET_FIELD", ('ETH_DST', 0x101112131415))]))
        set_field = OFPActionSetField(eth_src="10-11-12-13-14-15")
        self.assertEqual(
            actions_from_ryu([set_field], 'list'),
            ActionList([("SET_FIELD", ('ETH_SRC', 0x101112131415))]))
        set_field = OFPActionSetField(ipv4_dst="192.168.2.1")
        self.assertEqual(actions_from_ryu([set_field], 'list'),
                         ActionList([("SET_FIELD", ('IPV4_DST', 0xc0a80201))]))
        set_field = OFPActionSetField(ipv4_src="192.168.2.2")
        self.assertEqual(actions_from_ryu([set_field], 'list'),
                         ActionList([("SET_FIELD", ('IPV4_SRC', 0xc0a80202))]))
        set_field = OFPActionSetField(ipv6_src="::")
        self.assertEqual(actions_from_ryu([set_field], 'list'),
                         ActionList([("SET_FIELD", ('IPV6_SRC', 0x0))]))
        set_field = OFPActionSetField(
            ipv6_src="2001:DB8:0123:4567:89ab:cdef:a:a")
        ipv6_num = 0x20010DB80123456789abcdef000a000a
        self.assertEqual(actions_from_ryu([set_field], 'list'),
                         ActionList([("SET_FIELD", ('IPV6_SRC', ipv6_num))]))
        set_field = OFPActionSetField(ipv6_dst="2001:DB8::")
        ipv6_num = 0x20010DB8000000000000000000000000
        self.assertEqual(actions_from_ryu([set_field], 'list'),
                         ActionList([("SET_FIELD", ('IPV6_DST', ipv6_num))]))
        # TTL
        self.assertEqual(actions_from_ryu([OFPActionCopyTtlOut()], 'list'),
                         ActionList([('COPY_TTL_OUT', None)]))
        self.assertEqual(actions_from_ryu([OFPActionCopyTtlIn()], 'list'),
                         ActionList([('COPY_TTL_IN', None)]))
        self.assertEqual(actions_from_ryu([OFPActionSetMplsTtl(24)], 'list'),
                         ActionList([('SET_MPLS_TTL', 24)]))
        self.assertEqual(actions_from_ryu([OFPActionDecMplsTtl()], 'list'),
                         ActionList([('DEC_MPLS_TTL', None)]))
        self.assertEqual(actions_from_ryu([OFPActionSetNwTtl(0xff)], 'list'),
                         ActionList([('SET_NW_TTL', 0xff)]))
        self.assertEqual(actions_from_ryu([OFPActionDecNwTtl()], 'list'),
                         ActionList([('DEC_NW_TTL', None)]))
                 priority=0,
                 match=OFPMatch(),
                 instructions=[OFPInstructionGotoTable(1)]),

    # Table 1, ETH, IP etc.

    # Routing
    OFPFlowStats(table_id=1,
                 priority=1008,
                 match=parser.OFPMatch(eth_dst=1,
                                       ipv4_dst=("1.0.0.0", "255.0.0.0")),
                 instructions=[
                     OFPInstructionActions(ofproto_v1_3.OFPIT_APPLY_ACTIONS, [
                         OFPActionSetField(eth_src=100),
                         OFPActionSetField(eth_dst=20),
                         OFPActionOutput(20)
                     ])
                 ]),
    OFPFlowStats(table_id=1,
                 priority=1008,
                 match=OFPMatch(eth_dst=2, ipv4_dst=("1.0.0.0", "255.0.0.0")),
                 instructions=[
                     OFPInstructionActions(ofproto_v1_3.OFPIT_APPLY_ACTIONS, [
                         OFPActionSetField(eth_src=100),
                         OFPActionSetField(eth_dst=20),
                         OFPActionOutput(20)
                     ])
                 ]),
    OFPFlowStats(table_id=1,
                 priority=1008,
                 match=OFPMatch(eth_dst=1, ipv4_dst=("10.0.0.0", "255.0.0.0")),
FW = []
LEARN = []
m = next_mac()
p = next_port()
for x in range(NUMBER_MACS):
    mac = m.next()
    port = p.next()
    FW.append(
        OFPFlowStats(table_id=2,
                     priority=1000,
                     match=OFPMatch(eth_dst=mac),
                     instructions=[
                         OFPInstructionActions(
                             ofproto_v1_3.OFPIT_WRITE_ACTIONS,
                             [OFPActionOutput(port)]),
                         OFPInstructionGotoTable(3)
                     ]))
    LEARN.append(
        OFPFlowStats(table_id=4,
                     priority=1000,
                     match=OFPMatch(in_port=port, eth_src=mac),
                     instructions=[]))

flows = [
    # Table 0 Mac Term
    OFPFlowStats(table_id=0,
                 priority=1000,
                 match=OFPMatch(eth_dst=1),
                 instructions=[OFPInstructionGotoTable(1)]),
    OFPFlowStats(table_id=0,
Пример #13
0
    def get_semantic_flows(self):
        rq = """
        PREFIX : <http://home.eps.hw.ac.uk/~qz1/>
        select ?p ?param ?val
        where
        {
          {
            ?p rdf:type/rdfs:subClassOf* of:Flow;
            ?param ?val.
          }
          UNION
          {
          ?flow rdf:type/rdfs:subClassOf* of:Flow;
              of:hasAction ?p.
            ?p ?param ?val.
          }
          UNION
          {
          ?p rdf:type/rdfs:subClassOf* of:Flow.
            ?sw ?param ?p.
            ?sw :hasID ?val.
          }
        }
        """
        res = self.store.query(rq)
        flows = {}
        actions = {}
        ret = {}

        for (a, b, c) in res:
            a = a.replace("http://home.eps.hw.ac.uk/~qz1/", "").encode()
            b = b.replace("http://home.eps.hw.ac.uk/~qz1/", "").encode()
            c = c.replace("http://home.eps.hw.ac.uk/~qz1/", "").encode()
            LOG.debug("%s %s %s" % (a, b, c))
            if "hasAction" in b:
                actions[c] = a
            if "_action" in a:
                if a not in flows[actions[a]]["actions"]:
                    flows[actions[a]]["actions"][a] = {}
                flows[actions[a]]["actions"][a][b] = c
            else:
                if a not in flows:
                    # We need a datapath here
                    flows[a] = {"match": {}, "datapath": None, "actions": {}}

                if b in mappings:
                    if b in ["in_port"]:
                        flows[a]["match"][b] = int(
                            c)  # append_field(self.match_map[b], c)
                    else:
                        flows[a]["match"][
                            b] = c  # append_field(self.match_map[b], c)
                if "hasFlow" in b:
                    flows[a]["datapath"] = int(c)
        for a in flows:
            dpid = flows[a]["datapath"]
            if dpid not in ret:
                ret[dpid] = []
            flow_act = []
            for act in flows[a]["actions"]:
                action = flows[a]["actions"][act]
                if action[
                        "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"] == "ActionOutput":
                    flow_act.append(
                        OFPActionOutput(int(action["toPort"]), max_len=0xffff))
            flow_act = [
                OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, flow_act)
            ]
            # flows[a]["match"] = OFPMatch(**flows[a]["match"])
            ret[dpid].append({
                "actions": flow_act,
                "match": OFPMatch(**flows[a]["match"])
            })
        return ret