Пример #1
0
    def _install_not_processed_flows(self, datapath, imsi, rule, rule_num,
                                     priority):
        """
        Redirect all traffic to the scratch table to only allow redirected
        http traffic to go through, the rest will be dropped. reg0 is used as
        a boolean to know whether the drop rule was processed.
        """
        parser = datapath.ofproto_parser
        of_note = parser.NXActionNote(list(rule.id.encode()))

        match = MagmaMatch(imsi=encode_imsi(imsi),
                           direction=Direction.OUT,
                           reg0=self.REDIRECT_NOT_PROCESSED,
                           eth_type=ether_types.ETH_TYPE_IP)
        action = [of_note]
        flows.add_resubmit_current_service_flow(
            datapath, self.main_tbl_num, match, action, priority=priority,
            cookie=rule_num, hard_timeout=rule.hard_timeout,
            resubmit_table=self._scratch_tbl_num)

        match = MagmaMatch(imsi=encode_imsi(imsi),
                           direction=Direction.OUT,
                           reg0=self.REDIRECT_PROCESSED)
        action = [of_note]
        flows.add_resubmit_next_service_flow(
            datapath, self.main_tbl_num, match, action, priority=priority,
            cookie=rule_num, hard_timeout=rule.hard_timeout,
            resubmit_table=self.next_table)
Пример #2
0
    def _install_scratch_table_flows(self, datapath, imsi, rule, rule_num,
                                     rule_version, priority):
        """
        The flow action for subscribers that need to be redirected does 2 things
            * Forward requests from subscriber to the internal http server
            * Instantiate a flow that matches response packets from the server
              and sends them back to subscriber
        Match: incoming tcp traffic with port 80, direction out
        Action:
            1) Set reg2 to rule_num
            2) Set ip dst to server ip
            3) Output to table 20
            4) Apply LearnAction:
            LearnAction(adds new flow for every pkt flow that hits this rule)
                1) Match ip packets
                2) Match tcp protocol
                3) Match packets from LOCAL port
                4) Match ip src = server ip
                5) Match ip dst = current flow ip src
                6) Match tcp src = current flow tcp dst
                7) Match tcp dst = current flow tcp src
                8) Load ip src = current flow ip dst
                9) Output through gtp0
        """
        parser = datapath.ofproto_parser
        match_http = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                                ip_proto=IPPROTO_TCP,
                                tcp_dst=80,
                                imsi=encode_imsi(imsi),
                                direction=Direction.OUT)
        of_note = parser.NXActionNote(list(rule.id.encode()))

        actions = [
            parser.NXActionLearn(
                table_id=self.main_tbl_num,
                priority=priority,
                cookie=rule_num,
                specs=[
                    parser.NXFlowSpecMatch(src=ether_types.ETH_TYPE_IP,
                                           dst=('eth_type_nxm', 0),
                                           n_bits=16),
                    parser.NXFlowSpecMatch(src=IPPROTO_TCP,
                                           dst=('ip_proto_nxm', 0),
                                           n_bits=8),
                    parser.NXFlowSpecMatch(src=Direction.IN,
                                           dst=(DIRECTION_REG, 0),
                                           n_bits=32),
                    parser.NXFlowSpecMatch(src=int(
                        ipaddress.IPv4Address(self._bridge_ip)),
                                           dst=('ipv4_src_nxm', 0),
                                           n_bits=32),
                    parser.NXFlowSpecMatch(src=('ipv4_src_nxm', 0),
                                           dst=('ipv4_dst_nxm', 0),
                                           n_bits=32),
                    parser.NXFlowSpecMatch(src=('tcp_src_nxm', 0),
                                           dst=('tcp_dst_nxm', 0),
                                           n_bits=16),
                    parser.NXFlowSpecMatch(src=self._redirect_port,
                                           dst=('tcp_src_nxm', 0),
                                           n_bits=16),
                    parser.NXFlowSpecMatch(src=encode_imsi(imsi),
                                           dst=(IMSI_REG, 0),
                                           n_bits=64),
                    parser.NXFlowSpecLoad(src=('ipv4_dst_nxm', 0),
                                          dst=('ipv4_src_nxm', 0),
                                          n_bits=32),
                    parser.NXFlowSpecLoad(src=80,
                                          dst=('tcp_src_nxm', 0),
                                          n_bits=16),
                    # Learn doesn't support resubmit to table, so send directly
                    parser.NXFlowSpecOutput(src=('in_port', 0),
                                            dst="",
                                            n_bits=16),
                ]),
            parser.NXActionRegLoad2(dst=SCRATCH_REGS[0],
                                    value=self.REDIRECT_PROCESSED),
            parser.OFPActionSetField(ipv4_dst=self._bridge_ip),
            parser.OFPActionSetField(tcp_dst=self._redirect_port),
            of_note,
        ]
        actions += self._load_rule_actions(parser, rule_num, rule_version)

        flows.add_resubmit_current_service_flow(
            datapath,
            self._scratch_tbl_num,
            match_http,
            actions,
            priority=priority,
            cookie=rule_num,
            hard_timeout=rule.hard_timeout,
            resubmit_table=self.main_tbl_num)

        match = MagmaMatch(imsi=encode_imsi(imsi))
        action = []
        flows.add_drop_flow(datapath,
                            self._scratch_tbl_num,
                            match,
                            action,
                            priority=flows.MINIMUM_PRIORITY + 1,
                            cookie=rule_num)