示例#1
0
文件: gy.py 项目: go-magma/magma
    def _install_default_flows_if_not_installed(
            self, datapath,
            existing_flows: List[OFPFlowStats]) -> List[OFPFlowStats]:
        inbound_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                                   direction=Direction.IN)
        outbound_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                                    direction=Direction.OUT)

        inbound_msg = flows.get_add_resubmit_next_service_flow_msg(
            datapath,
            self.tbl_num,
            inbound_match, [],
            priority=flows.MINIMUM_PRIORITY,
            resubmit_table=self.next_main_table)

        outbound_msg = flows.get_add_resubmit_next_service_flow_msg(
            datapath,
            self.tbl_num,
            outbound_match, [],
            priority=flows.MINIMUM_PRIORITY,
            resubmit_table=self.next_main_table)

        msgs, remaining_flows = self._msg_hub \
            .filter_msgs_if_not_in_flow_list([inbound_msg, outbound_msg],
                                             existing_flows)
        if msgs:
            chan = self._msg_hub.send(msgs, datapath)
            self._wait_for_responses(chan, len(msgs))

        return remaining_flows
示例#2
0
    def _get_rule_match_flow_msgs(self, imsi, rule_num, rule_id):
        """
        Returns flow add messages used for rule matching.
        """
        version = self._session_rule_version_mapper.get_version(imsi, rule_id)
        self.logger.debug(
            'Installing flow for %s with rule num %s (version %s)', imsi,
            rule_num, version)
        inbound_rule_match = _generate_rule_match(imsi, rule_num, version,
                                                  Direction.IN)
        outbound_rule_match = _generate_rule_match(imsi, rule_num, version,
                                                   Direction.OUT)

        return [
            flows.get_add_resubmit_next_service_flow_msg(
                self._datapath,
                self.tbl_num,
                inbound_rule_match, [],
                priority=flows.DEFAULT_PRIORITY,
                cookie=rule_num,
                resubmit_table=self.next_table),
            flows.get_add_resubmit_next_service_flow_msg(
                self._datapath,
                self.tbl_num,
                outbound_rule_match, [],
                priority=flows.DEFAULT_PRIORITY,
                cookie=rule_num,
                resubmit_table=self.next_table),
        ]
示例#3
0
 def _get_rule_match_flow_msgs(self, imsi, rule_num):
     """
     Returns flows used for usage reporting in enforcement_stats. These
     flows match on reg2, which stores the rule num to get usage for each
     rule.
     """
     inbound_rule_match = MagmaMatch(imsi=encode_imsi(imsi),
                                     direction=Direction.IN,
                                     reg2=rule_num)
     outbound_rule_match = MagmaMatch(imsi=encode_imsi(imsi),
                                      direction=Direction.OUT,
                                      reg2=rule_num)
     return [
         flows.get_add_resubmit_next_service_flow_msg(
             self._datapath,
             self._enforcement_stats_scratch,
             inbound_rule_match, [],
             priority=flows.DEFAULT_PRIORITY,
             cookie=rule_num,
             resubmit_table=self.next_main_table),
         flows.get_add_resubmit_next_service_flow_msg(
             self._datapath,
             self._enforcement_stats_scratch,
             outbound_rule_match, [],
             priority=flows.DEFAULT_PRIORITY,
             cookie=rule_num,
             resubmit_table=self.next_main_table),
     ]
示例#4
0
    def _get_default_middle_flow_msgs(self, dp):
        """
        Egress table is the last table that a packet touches in the pipeline.
        Output downlink traffic to gtp port, uplink trafic to LOCAL

        Raises:
            MagmaOFError if any of the default flows fail to install.
        """
        msgs = []
        next_tbl = self._service_manager.get_next_table_num(PHYSICAL_TO_LOGICAL)

        # Allow passthrough pkts(skip enforcement and send to egress table)
        ps_match = MagmaMatch(passthrough=PASSTHROUGH_REG_VAL)
        msgs.append(flows.get_add_resubmit_next_service_flow_msg(dp,
            self._midle_tbl_num, ps_match, actions=[],
            priority=flows.PASSTHROUGH_PRIORITY,
            resubmit_table=self._egress_tbl_num))

        match = MagmaMatch()
        msgs.append(flows.get_add_resubmit_next_service_flow_msg(dp,
            self._midle_tbl_num, match, actions=[],
            priority=flows.DEFAULT_PRIORITY, resubmit_table=next_tbl))

        if self._mtr_service_enabled:
            msgs.extend(_get_vlan_egress_flow_msgs(dp,
                                       self._midle_tbl_num,
                                       self.config.mtr_ip,
                                       self.config.mtr_port,
                                       priority=flows.UE_FLOW_PRIORITY,
                                       direction=Direction.OUT))
        return msgs
    def _get_rule_match_flow_msgs(self, imsi, ip_addr, ambr, rule):
        """
        Returns flow add messages used for rule matching.
        """
        rule_num = self._rule_mapper.get_or_create_rule_num(rule.id)
        version = self._session_rule_version_mapper.get_version(imsi, ip_addr,
                                                                rule.id)
        self.logger.debug(
            'Installing flow for %s with rule num %s (version %s)', imsi,
            rule_num, version)
        inbound_rule_match = _generate_rule_match(imsi, ip_addr, rule_num,
                                                  version, Direction.IN)
        outbound_rule_match = _generate_rule_match(imsi, ip_addr, rule_num,
                                                   version, Direction.OUT)

        inbound_rule_match._match_kwargs[SCRATCH_REGS[1]] = PROCESS_STATS
        outbound_rule_match._match_kwargs[SCRATCH_REGS[1]] = PROCESS_STATS
        msgs = [
            flows.get_add_resubmit_next_service_flow_msg(
                self._datapath,
                self.tbl_num,
                inbound_rule_match,
                [],
                priority=flows.DEFAULT_PRIORITY,
                cookie=rule_num,
                resubmit_table=self.next_table),
            flows.get_add_resubmit_next_service_flow_msg(
                self._datapath,
                self.tbl_num,
                outbound_rule_match,
                [],
                priority=flows.DEFAULT_PRIORITY,
                cookie=rule_num,
                resubmit_table=self.next_table),
        ]

        if rule.app_name:
            inbound_rule_match._match_kwargs[SCRATCH_REGS[1]] = IGNORE_STATS
            outbound_rule_match._match_kwargs[SCRATCH_REGS[1]] = IGNORE_STATS
            msgs.extend([
                flows.get_add_resubmit_next_service_flow_msg(
                    self._datapath,
                    self.tbl_num,
                    inbound_rule_match,
                    [],
                    priority=flows.DEFAULT_PRIORITY,
                    cookie=rule_num,
                    resubmit_table=self.next_table),
                flows.get_add_resubmit_next_service_flow_msg(
                    self._datapath,
                    self.tbl_num,
                    outbound_rule_match,
                    [],
                    priority=flows.DEFAULT_PRIORITY,
                    cookie=rule_num,
                    resubmit_table=self.next_table),
            ])
        return msgs
示例#6
0
    def _install_default_flows_if_not_installed(self, datapath,
            existing_flows: List[OFPFlowStats]) -> List[OFPFlowStats]:
        """
        For each direction set the default flows to just forward to next app.
        The enforcement flows for each subscriber would be added when the
        IP session is created, by reaching out to the controller/PCRF.
        If default flows are already installed, do nothing.

        Args:
            datapath: ryu datapath struct
        Returns:
            The list of flows that remain after inserting default flows
        """
        match = MagmaMatch()

        msg = flows.get_add_resubmit_next_service_flow_msg(
            datapath, self.tbl_num, match, [],
            priority=flows.MINIMUM_PRIORITY,
            resubmit_table=self.next_main_table)

        msgs, remaining_flows = self._msg_hub \
            .filter_msgs_if_not_in_flow_list([msg], existing_flows)
        if msgs:
            chan = self._msg_hub.send(msgs, datapath)
            self._wait_for_responses(chan, len(msgs))

        return remaining_flows
示例#7
0
    def _install_default_flows_if_not_installed(
            self, datapath,
            existing_flows: List[OFPFlowStats]) -> List[OFPFlowStats]:
        """
        Install default flows(if not already installed) to forward the traffic,
        If no other flows are matched.

        Returns:
            The list of flows that remain after inserting default flows
        """
        match = MagmaMatch()
        msg = flows.get_add_resubmit_next_service_flow_msg(
            datapath,
            self.tbl_num,
            match, [],
            priority=flows.MINIMUM_PRIORITY,
            resubmit_table=self.next_table,
            cookie=self.DEFAULT_FLOW_COOKIE)

        msg, remaining_flows = \
            self._msg_hub.filter_msgs_if_not_in_flow_list([msg], existing_flows)
        if msg:
            chan = self._msg_hub.send(msg, datapath)
            self._wait_for_responses(chan, 1)

        return remaining_flows
示例#8
0
文件: gy.py 项目: maniacs-ops/magma-1
    def _get_default_flow_msgs(self, datapath) -> DefaultMsgsMap:
        """
        Gets the default flow msg that forwards to next service

        Args:
            datapath: ryu datapath struct
        Returns:
            The list of default msgs to add
        """
        match = MagmaMatch()
        msg = flows.get_add_resubmit_next_service_flow_msg(
            datapath, self.tbl_num, match, [],
            priority=flows.MINIMUM_PRIORITY,
            resubmit_table=self.next_main_table)

        return {self.tbl_num: [msg]}
示例#9
0
    def _get_default_flow_msgs(self, datapath) -> DefaultMsgsMap:
        """
        Gets the default flow msg that forward to stats table(traffic will be
        dropped because stats table doesn't forward anything)

        Args:
            datapath: ryu datapath struct
        Returns:
            The list of default msgs to add
        """
        match = MagmaMatch()
        msg = flows.get_add_resubmit_next_service_flow_msg(
            datapath, self.tbl_num, match, [],
            priority=flows.MINIMUM_PRIORITY,
            resubmit_table=self._enforcement_stats_tbl,
            cookie=self.DEFAULT_FLOW_COOKIE,
        )

        return {self.tbl_num: [msg]}
示例#10
0
    def _get_classify_rule_flow_msg(self, imsi, flow, rule_num, priority,
                                    ul_qos, dl_qos, hard_timeout, rule_id):
        """
        Install a flow from a rule. If the flow action is DENY, then the flow
        will drop the packet. Otherwise, the flow classifies the packet with
        its matched rule and injects the rule num into the packet's register.
        """
        flow_match = flow_match_to_magma_match(flow.match)
        flow_match.imsi = encode_imsi(imsi)
        flow_match_actions = self._get_classify_rule_of_actions(
            flow, rule_num, imsi, ul_qos, dl_qos, rule_id)
        if flow.action == flow.DENY:
            return flows.get_add_drop_flow_msg(self._datapath,
                                               self.tbl_num,
                                               flow_match,
                                               flow_match_actions,
                                               hard_timeout=hard_timeout,
                                               priority=priority,
                                               cookie=rule_num)

        if self._enforcement_stats_scratch:
            return flows.get_add_resubmit_current_service_flow_msg(
                self._datapath,
                self.tbl_num,
                flow_match,
                flow_match_actions,
                hard_timeout=hard_timeout,
                priority=priority,
                cookie=rule_num,
                resubmit_table=self._enforcement_stats_scratch)

        # If enforcement stats has not claimed a scratch table, resubmit
        # directly to the next app.
        return flows.get_add_resubmit_next_service_flow_msg(
            self._datapath,
            self.tbl_num,
            flow_match,
            flow_match_actions,
            hard_timeout=hard_timeout,
            priority=priority,
            cookie=rule_num,
            resubmit_table=self.next_main_table)
示例#11
0
    def _get_default_ingress_flow_msgs(self, dp):
        """
        Sets up the ingress table, the first step in the packet processing
        pipeline.

        This sets up flow rules to annotate packets with a metadata bit
        indicating the direction. Incoming packets are defined as packets
        originating from the LOCAL port, outgoing packets are defined as
        packets originating from the gtp port.

        All other packets bypass the pipeline.

        Note that the ingress rules do *not* install any flows that cause
        PacketIns (i.e., sends packets to the controller).

        Raises:
            MagmaOFError if any of the default flows fail to install.
        """
        parser = dp.ofproto_parser
        next_table = self._service_manager.get_next_table_num(INGRESS)
        msgs = []

        # set traffic direction bits

        # set a direction bit for incoming (internet -> UE) traffic.
        match = MagmaMatch(in_port=OFPP_LOCAL)
        actions = [load_direction(parser, Direction.IN)]
        msgs.append(
            flows.get_add_resubmit_next_service_flow_msg(
                dp,
                self._ingress_tbl_num,
                match,
                actions=actions,
                priority=flows.DEFAULT_PRIORITY,
                resubmit_table=next_table))

        # set a direction bit for incoming (internet -> UE) traffic.
        match = MagmaMatch(in_port=self.config.uplink_port)
        actions = [load_direction(parser, Direction.IN)]
        msgs.append(
            flows.get_add_resubmit_next_service_flow_msg(
                dp,
                self._ingress_tbl_num,
                match,
                actions=actions,
                priority=flows.DEFAULT_PRIORITY,
                resubmit_table=next_table))

        # Send RADIUS requests directly to li table
        if self._li_port:
            match = MagmaMatch(in_port=self._li_port)
            actions = [load_direction(parser, Direction.IN)]
            msgs.append(
                flows.get_add_resubmit_next_service_flow_msg(
                    dp,
                    self._ingress_tbl_num,
                    match,
                    actions=actions,
                    priority=flows.DEFAULT_PRIORITY,
                    resubmit_table=self._li_table))

        # set a direction bit for incoming (mtr -> UE) traffic.
        if self._mtr_service_enabled:
            match = MagmaMatch(in_port=self.config.mtr_port)
            actions = [load_direction(parser, Direction.IN)]
            msgs.append(
                flows.get_add_resubmit_next_service_flow_msg(
                    dp,
                    self._ingress_tbl_num,
                    match,
                    actions=actions,
                    priority=flows.DEFAULT_PRIORITY,
                    resubmit_table=next_table))

        if self.config.he_proxy_port != 0:
            match = MagmaMatch(in_port=self.config.he_proxy_port)
            actions = [load_direction(parser, Direction.IN)]
            msgs.append(
                flows.get_add_resubmit_next_service_flow_msg(
                    dp,
                    self._ingress_tbl_num,
                    match,
                    actions=actions,
                    priority=flows.DEFAULT_PRIORITY,
                    resubmit_table=next_table))

        if self.config.setup_type == 'CWF':
            # set a direction bit for outgoing (pn -> inet) traffic for remaining traffic
            ps_match_out = MagmaMatch()
            actions = [load_direction(parser, Direction.OUT)]
            msgs.append(
                flows.get_add_resubmit_next_service_flow_msg(
                    dp,
                    self._ingress_tbl_num,
                    ps_match_out,
                    actions=actions,
                    priority=flows.MINIMUM_PRIORITY,
                    resubmit_table=next_table))
        else:
            # set a direction bit for outgoing (pn -> inet) traffic for remaining traffic
            # Passthrough is zero for packets from eNodeB GTP tunnels
            ps_match_out = MagmaMatch(passthrough=REG_ZERO_VAL)
            actions = [load_direction(parser, Direction.OUT)]
            msgs.append(
                flows.get_add_resubmit_next_service_flow_msg(
                    dp,
                    self._ingress_tbl_num,
                    ps_match_out,
                    actions=actions,
                    priority=flows.MINIMUM_PRIORITY,
                    resubmit_table=next_table))

            # Passthrough is one for packets from remote PGW GTP tunnels, set direction
            # flag to IN for such packets.
            ps_match_in = MagmaMatch(passthrough=PASSTHROUGH_REG_VAL)
            actions = [load_direction(parser, Direction.IN)]
            msgs.append(
                flows.get_add_resubmit_next_service_flow_msg(
                    dp,
                    self._ingress_tbl_num,
                    ps_match_in,
                    actions=actions,
                    priority=flows.MINIMUM_PRIORITY,
                    resubmit_table=next_table))

        return msgs