Example #1
0
    def _add_dhcp_passthrough_flows(self, sid, mac_addr):
        ofproto, parser = self._datapath.ofproto, self._datapath.ofproto_parser

        # Set so packet skips enforcement controller
        action = load_passthrough(parser)
        uplink_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                                  ip_proto=IPPROTO_UDP,
                                  udp_src=68,
                                  udp_dst=67,
                                  eth_src=mac_addr)
        self._add_resubmit_flow(sid, uplink_match, action,
                                flows.PASSTHROUGH_PRIORITY)

        downlink_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                                    ip_proto=IPPROTO_UDP,
                                    udp_src=67,
                                    udp_dst=68,
                                    eth_dst=mac_addr)
        # Set so triggers packetin and we can learn the ip to do arp response
        self._add_resubmit_flow(sid,
                                downlink_match,
                                action,
                                flows.PASSTHROUGH_PRIORITY,
                                next_table=self._dhcp_learn_scratch)

        # Install default flow for dhcp learn scratch
        imsi_match = MagmaMatch(imsi=encode_imsi(sid))
        flows.add_output_flow(self._datapath,
                              self._dhcp_learn_scratch,
                              match=imsi_match,
                              actions=[],
                              priority=flows.PASSTHROUGH_PRIORITY,
                              output_port=ofproto.OFPP_CONTROLLER,
                              copy_table=self.next_table,
                              max_len=ofproto.OFPCML_NO_BUFFER)
Example #2
0
 def _deactivate_flows_for_subscriber(self, imsi):
     """ Deactivate all rules for a subscriber, ending any enforcement """
     match = MagmaMatch(imsi=encode_imsi(imsi))
     flows.delete_flow(self._datapath, self.tbl_num, match)
     self._redirect_manager.deactivate_flows_for_subscriber(
         self._datapath, imsi)
     self._qos_map.del_subscriber_queues(imsi)
Example #3
0
    def _add_resubmit_flow(self,
                           sid,
                           match,
                           action=None,
                           priority=flows.DEFAULT_PRIORITY,
                           next_table=None,
                           tbl_num=None):
        parser = self._datapath.ofproto_parser

        if action is None:
            actions = []
        else:
            actions = [action]
        if next_table is None:
            next_table = self.next_table
        if tbl_num is None:
            tbl_num = self.tbl_num

        # Add IMSI metadata
        actions.append(
            parser.NXActionRegLoad2(dst=IMSI_REG, value=encode_imsi(sid)))

        flows.add_resubmit_next_service_flow(self._datapath,
                                             tbl_num,
                                             match,
                                             actions=actions,
                                             priority=priority,
                                             resubmit_table=next_table)
Example #4
0
    def add_ue_sample_flow(self, imsi: str, msisdn: str,
                           apn_mac_addr: str, apn_name: str) -> None:
        """
        Install a flow to sample packets for IPFIX for specific imsi

        Args:
            imsi (string): subscriber to install rule for
            msisdn (string): msisdn string
            apn_mac_addr (string): AP mac address string
            apn_name (string): AP name
        """
        if self._datapath is None:
            self.logger.error('Datapath not initialized for adding flows')
            return

        imsi_hex = hex(encode_imsi(imsi))
        pdp_start_epoch = int(time.time())
        action_str = (
            'ovs-ofctl add-flow {} "table={},priority={},metadata={},'
            'actions=sample(probability={},collector_set_id={},'
            'obs_domain_id={},obs_point_id={},apn_mac_addr={},msisdn={},'
            'apn_name=\\\"{}\\\",pdp_start_epoch={},sampling_port={}),'
            'resubmit(,{})"'
        ).format(
            self._bridge_name, self.tbl_num, flows.UE_FLOW_PRIORITY, imsi_hex,
            self.ipfix_config.probability, self.ipfix_config.collector_set_id,
            self.ipfix_config.obs_domain_id, self.ipfix_config.obs_point_id,
            apn_mac_addr.replace("-", ":"), msisdn, apn_name, pdp_start_epoch,
            self.ipfix_config.sampling_port, self.next_main_table
        )
        try:
            subprocess.Popen(action_str, shell=True).wait()
        except subprocess.CalledProcessError as e:
            raise Exception('Error: {} failed with: {}'.format(action_str, e))
Example #5
0
    def _deactivate_flows_for_subscriber(self, imsi, ip_addr):
        """ Deactivate all rules for specified subscriber session """
        ip_match_in = get_ue_ip_match_args(ip_addr, Direction.IN)
        match = MagmaMatch(eth_type=get_eth_type(ip_addr),
                           imsi=encode_imsi(imsi),
                           **ip_match_in)
        flows.delete_flow(self._datapath, self.tbl_num, match)
        ip_match_out = get_ue_ip_match_args(ip_addr, Direction.OUT)
        match = MagmaMatch(eth_type=get_eth_type(ip_addr),
                           imsi=encode_imsi(imsi),
                           **ip_match_out)
        flows.delete_flow(self._datapath, self.tbl_num, match)

        self._redirect_manager.deactivate_flows_for_subscriber(
            self._datapath, imsi)
        self._qos_mgr.remove_subscriber_qos(imsi)
Example #6
0
    def _deactivate_flow_for_rule(self, imsi, ip_addr, rule_id):
        """
        Deactivate a specific rule using the flow cookie for a subscriber

        Args:
            imsi (string): subscriber id
            rule_id (string): policy rule id
        """
        try:
            num = self._rule_mapper.get_rule_num(rule_id)
        except KeyError:
            self.logger.error('Could not find rule id %s', rule_id)
            return
        cookie, mask = (num, flows.OVS_COOKIE_MATCH_ALL)
        match = MagmaMatch(imsi=encode_imsi(imsi))
        flows.delete_flow(
            self._datapath,
            self.tbl_num,
            match,
            cookie=cookie,
            cookie_mask=mask,
        )
        self._redirect_manager.deactivate_flow_for_rule(
            self._datapath,
            imsi,
            num,
        )
        if self._qos_mgr:
            self._qos_mgr.remove_subscriber_qos(imsi, num)
        self._remove_he_flows(ip_addr, rule_id)
Example #7
0
 def _install_dns_flows(self, datapath, imsi, rule, rule_num, priority):
     """
     Installs flows that allow DNS queries to path thorugh.
     """
     parser = datapath.ofproto_parser
     of_note = parser.NXActionNote(list(rule.id.encode()))
     actions = [
         parser.NXActionRegLoad2(dst='reg2', value=rule_num),
         of_note,
     ]
     matches = []
     # Install UDP flows for DNS
     matches.append(
         MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                    ip_proto=IPPROTO_UDP,
                    udp_src=53,
                    direction=Direction.IN,
                    imsi=encode_imsi(imsi)))
     matches.append(
         MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                    ip_proto=IPPROTO_UDP,
                    udp_dst=53,
                    direction=Direction.OUT,
                    imsi=encode_imsi(imsi)))
     # Install TCP flows for DNS
     matches.append(
         MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                    ip_proto=IPPROTO_TCP,
                    tcp_src=53,
                    direction=Direction.IN,
                    imsi=encode_imsi(imsi)))
     matches.append(
         MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                    ip_proto=IPPROTO_TCP,
                    tcp_dst=53,
                    direction=Direction.OUT,
                    imsi=encode_imsi(imsi)))
     for match in matches:
         flows.add_resubmit_next_service_flow(
             datapath,
             self.main_tbl_num,
             match,
             actions,
             priority=priority,
             cookie=rule_num,
             hard_timeout=rule.hard_timeout,
             resubmit_table=self.next_table)
Example #8
0
    def _add_subscriber_flow(self, imsi: str, ue_mac: str, has_quota: bool):
        """
        Redirect the UE flow to the dedicated flask server.
        On return traffic rewrite the IP/port so the redirection is seamless.
        """
        parser = self._datapath.ofproto_parser
        if has_quota:
            tcp_dst = self.config.has_quota_port
        else:
            tcp_dst = self.config.no_quota_port
        match = MagmaMatch(imsi=encode_imsi(imsi),
                           eth_type=ether_types.ETH_TYPE_IP,
                           ip_proto=IPPROTO_TCP,
                           direction=Direction.OUT,
                           vlan_vid=(0x1000, 0x1000),
                           ipv4_dst=self.config.quota_check_ip)
        actions = [
            parser.OFPActionSetField(ipv4_dst=self.config.bridge_ip),
            parser.OFPActionSetField(eth_dst=self.config.cwf_bridge_mac),
            parser.OFPActionSetField(tcp_dst=tcp_dst),
            parser.OFPActionPopVlan()
        ]
        flows.add_output_flow(self._datapath,
                              self.tbl_num,
                              match,
                              actions,
                              priority=flows.UE_FLOW_PRIORITY,
                              output_port=OFPP_LOCAL)

        # For traffic from the check quota server rewrite src ip and port
        match = MagmaMatch(imsi=encode_imsi(imsi),
                           eth_type=ether_types.ETH_TYPE_IP,
                           ip_proto=IPPROTO_TCP,
                           direction=Direction.IN,
                           ipv4_src=self.config.bridge_ip)
        actions = [
            parser.OFPActionSetField(ipv4_src=self.config.quota_check_ip),
            parser.OFPActionSetField(eth_dst=ue_mac),
            parser.OFPActionSetField(tcp_src=80)
        ]
        flows.add_resubmit_next_service_flow(
            self._datapath,
            self.tbl_num,
            match,
            actions,
            priority=flows.DEFAULT_PRIORITY,
            resubmit_table=self.next_main_table)
Example #9
0
    def _deactivate_flow_for_rule(self, imsi, ip_addr, rule_id):
        """
        Deactivate a specific rule using the flow cookie for a subscriber
        """
        try:
            num = self._rule_mapper.get_rule_num(rule_id)
        except KeyError:
            self.logger.error('Could not find rule id %s', rule_id)
            return
        if num is None:
            self.logger.error('Rule num is None for rule %s', rule_id)
            return
        cookie, mask = (num, flows.OVS_COOKIE_MATCH_ALL)

        ip_match_in = get_ue_ip_match_args(ip_addr, Direction.IN)
        match = MagmaMatch(
            eth_type=get_eth_type(ip_addr),
            imsi=encode_imsi(imsi),
            **ip_match_in,
        )
        flows.delete_flow(
            self._datapath,
            self.tbl_num,
            match,
            cookie=cookie,
            cookie_mask=mask,
        )
        ip_match_out = get_ue_ip_match_args(ip_addr, Direction.OUT)
        match = MagmaMatch(
            eth_type=get_eth_type(ip_addr),
            imsi=encode_imsi(imsi),
            **ip_match_out,
        )
        flows.delete_flow(
            self._datapath,
            self.tbl_num,
            match,
            cookie=cookie,
            cookie_mask=mask,
        )
        self._redirect_manager.deactivate_flow_for_rule(
            self._datapath,
            imsi,
            num,
        )
        self._qos_mgr.remove_subscriber_qos(imsi, num)
        self._remove_he_flows(ip_addr, rule_id, num)
Example #10
0
    def _get_classify_rule_flow_msgs(self, imsi, flow, rule_num, priority, qos,
                                     hard_timeout, rule_id, app_name,
                                     app_service_type):
        """
        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, instructions = self._get_classify_rule_of_actions(
            flow, rule_num, imsi, qos, rule_id)
        msgs = []
        if app_name:
            # We have to allow initial traffic to pass through, before it gets
            # classified by DPI, flow match set app_id to unclassified
            flow_match.app_id = UNCLASSIFIED_PROTO_ID
            # Set
            parser = self._datapath.ofproto_parser
            passthrough_actions = flow_match_actions + \
                [parser.NXActionRegLoad2(dst=SCRATCH_REGS[1],
                                         value=IGNORE_STATS)]
            msgs.append(
                flows.get_add_resubmit_current_service_flow_msg(
                    self._datapath,
                    self.tbl_num,
                    flow_match,
                    passthrough_actions,
                    hard_timeout=hard_timeout,
                    priority=self.UNCLASSIFIED_ALLOW_PRIORITY,
                    cookie=rule_num,
                    resubmit_table=self._enforcement_stats_scratch))
            flow_match.app_id = get_app_id(
                PolicyRule.AppName.Name(app_name),
                PolicyRule.AppServiceType.Name(app_service_type),
            )

        if flow.action == flow.DENY:
            msgs.append(
                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))
        else:
            msgs.append(
                flows.get_add_resubmit_current_service_flow_msg(
                    self._datapath,
                    self.tbl_num,
                    flow_match,
                    flow_match_actions,
                    instructions=instructions,
                    hard_timeout=hard_timeout,
                    priority=priority,
                    cookie=rule_num,
                    resubmit_table=self._enforcement_stats_scratch))
        return msgs
Example #11
0
    def add_ue_sample_flow(
        self, imsi: str, msisdn: str,
        apn_mac_addr: str, apn_name: str,
        pdp_start_time: int,
    ) -> None:
        """
        Install a flow to sample packets for IPFIX for specific imsi

        Args:
            imsi (string): subscriber to install rule for
            msisdn (string): msisdn string
            apn_mac_addr (string): AP mac address string
            apn_name (string): AP name
        """
        if self._datapath is None:
            self.logger.error('Datapath not initialized for adding flows')
            return

        if not self.ipfix_config.enabled:
            # TODO logging higher than debug here will provide too much noise
            # possible fix is making ipfix a dynamic service enabled from orc8r
            self.logger.debug('IPFIX export dst not setup for adding flows')
            return

        parser = self._datapath.ofproto_parser
        if not apn_mac_addr or '-' not in apn_mac_addr:
            apn_mac_bytes = [0, 0, 0, 0, 0, 0]
        else:
            apn_mac_bytes = [int(a, 16) for a in apn_mac_addr.split('-')]

        if not msisdn:
            msisdn = 'no_msisdn'

        actions = [
            parser.NXActionSample2(
                probability=self.ipfix_config.probability,
                collector_set_id=self.ipfix_config.collector_set_id,
                obs_domain_id=self.ipfix_config.obs_domain_id,
                obs_point_id=self.ipfix_config.obs_point_id,
                apn_mac_addr=apn_mac_bytes,
                msisdn=msisdn.encode('ascii'),
                apn_name=apn_name.encode('ascii'),
                pdp_start_epoch=pdp_start_time.to_bytes(8, byteorder='little'),
                sampling_port=self.ipfix_config.sampling_port,
            ),
        ]

        match = MagmaMatch(imsi=encode_imsi(imsi))
        if self._dpi_enabled or self._conntrackd_enabled:
            flows.add_drop_flow(
                self._datapath, self._ipfix_sample_tbl_num, match, actions,
                priority=flows.UE_FLOW_PRIORITY,
            )
        else:
            flows.add_resubmit_next_service_flow(
                self._datapath, self._ipfix_sample_tbl_num, match, actions,
                priority=flows.UE_FLOW_PRIORITY,
                resubmit_table=self.next_main_table,
            )
Example #12
0
def _generate_rule_match(imsi, rule_num, version, direction):
    """
    Return a MagmaMatch that matches on the rule num and the version.
    """
    return MagmaMatch(imsi=encode_imsi(imsi),
                      direction=direction,
                      reg2=rule_num,
                      rule_version=version)
Example #13
0
 def deactivate_flow_for_rule(self, datapath, imsi, rule_num):
     """
     Deactivate a specific rule using the flow cookie for a subscriber
     """
     cookie, mask = (rule_num, flows.OVS_COOKIE_MATCH_ALL)
     match = MagmaMatch(imsi=encode_imsi(imsi))
     flows.delete_flow(datapath, self._scratch_tbl_num, match,
                       cookie=cookie, cookie_mask=mask)
Example #14
0
 def _set_subscriber_match(self, sub_info):
     """ Sets up match/action for subscriber flows """
     if sub_info.ip.count(":") >= 2:
         self._match_kwargs = {"eth_type": ether_types.ETH_TYPE_IPV6}
     else:
         self._match_kwargs = {"eth_type": ether_types.ETH_TYPE_IP}
     return self.set_ip(sub_info.ip) \
         .set_reg_value(IMSI_REG, encode_imsi(sub_info.imsi))
Example #15
0
 def _get_default_flow_msg_for_subscriber(self, imsi):
     match = MagmaMatch(imsi=encode_imsi(imsi))
     actions = []
     return flows.get_add_drop_flow_msg(self._datapath,
                                        self.tbl_num,
                                        match,
                                        actions,
                                        priority=self.ENFORCE_DROP_PRIORITY)
Example #16
0
    def test_rule_install(self):
        """
        Adds a policy to a subscriber. Verifies that flows are properly
        installed in enforcement and enforcement stats.

        Assert:
            Policy classification flows installed in enforcement
            Policy match flows installed in enforcement_stats
        """
        imsi = 'IMSI001010000000013'
        sub_ip = '192.168.128.74'

        flow_list = [
            FlowDescription(match=FlowMatch(ipv4_dst='45.10.0.0/25',
                                            direction=FlowMatch.UPLINK),
                            action=FlowDescription.PERMIT)
        ]
        policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list)
        self.service_manager.session_rule_version_mapper.update_version(
            imsi, 'rule1')
        version = \
            self.service_manager.session_rule_version_mapper.get_version(
                imsi, 'rule1')
        """ Setup subscriber, setup table_isolation to fwd pkts """
        self._static_rule_dict[policy.id] = policy
        sub_context = RyuDirectSubscriberContext(
            imsi, sub_ip, self.enforcement_controller, self._main_tbl_num,
            self.enforcement_stats_controller).add_static_rule(policy.id)

        # =========================== Verification ===========================
        rule_num = self.enforcement_stats_controller._rule_mapper \
            .get_or_create_rule_num(policy.id)
        enf_query = FlowQuery(self._main_tbl_num,
                              self.testing_controller,
                              match=flow_match_to_magma_match(
                                  FlowMatch(ipv4_dst='45.10.0.0/25',
                                            direction=FlowMatch.UPLINK)),
                              cookie=rule_num)
        es_query = FlowQuery(self._scratch_tbl_num,
                             self.testing_controller,
                             match=MagmaMatch(imsi=encode_imsi(imsi),
                                              reg2=rule_num,
                                              rule_version=version),
                             cookie=rule_num)

        # Verifies that 1 flow is installed in enforcement and 2 flows are
        # installed in enforcement stats, one for uplink and one for downlink.
        flow_verifier = FlowVerifier([
            FlowTest(enf_query, 0, flow_count=1),
            FlowTest(es_query, 0, flow_count=2),
        ], lambda: None)
        snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
                                             self.service_manager)

        with sub_context, flow_verifier, snapshot_verifier:
            pass

        flow_verifier.verify()
Example #17
0
    def _ng_tunnel_update(self, pdr_entry: PDRRuleEntry,
                          subscriber_id: str) -> bool:

        ret = self._classifier_app.gtp_handler(
            pdr_entry.pdr_state, pdr_entry.precedence, pdr_entry.local_f_teid,
            pdr_entry.far_action.o_teid, pdr_entry.ue_ip_addr,
            pdr_entry.far_action.gnb_ip_addr, encode_imsi(subscriber_id), True)

        return ret
Example #18
0
 def _install_mirror_flows(self, imsis):
     parser = self._datapath.ofproto_parser
     for imsi in imsis:
         self.logger.debug("Enabling LI tracking for IMSI %s", imsi)
         match = MagmaMatch(imsi=encode_imsi(imsi))
         actions = [parser.OFPActionOutput(self._li_dst_port_num)]
         flows.add_resubmit_next_service_flow(self._datapath, self.tbl_num,
             match, actions, priority=flows.DEFAULT_PRIORITY,
             resubmit_table=self.next_table)
Example #19
0
 def _save_version_unsafe(
     self,
     imsi: str,
     ip_addr: str,
     rule_id: str,
     version,
 ):
     key = self._get_json_key(encode_imsi(imsi), ip_addr, rule_id)
     self._version_by_imsi_and_rule[key] = version
Example #20
0
 def deactivate_flows_for_subscriber(self, datapath, imsi):
     """
     Deactivate all rules for a subscriber
     """
     flows.delete_flow(
         datapath,
         self._scratch_tbl_num,
         MagmaMatch(imsi=encode_imsi(imsi)),
     )
Example #21
0
def create_ue_session_entry(tunnel_msg: UESessionSet) -> UESessionSet:
    """Do create named tuple from input message

    Args:
        tunnel_msg: Message from MME

    Returns:
           UESessionSet
    """
    sid = 0
    ue_ipv4_address = None
    ue_ipv6_address = None
    enb_ipv4_address = None
    apn = None

    if tunnel_msg.subscriber_id.id:
        sid = encode_imsi(tunnel_msg.subscriber_id.id)

    if tunnel_msg.ue_ipv4_address.address:
        addr_str = socket.inet_ntop(
            socket.AF_INET,
            tunnel_msg.ue_ipv4_address.address,
        )
        ue_ipv4_address = IPAddress(
            version=tunnel_msg.ue_ipv4_address.version,
            address=addr_str.encode('utf8'),
        )

    if tunnel_msg.ue_ipv6_address.address:
        addr_str = socket.inet_ntop(
            socket.AF_INET6,
            tunnel_msg.ue_ipv6_address.address,
        )
        ue_ipv6_address = IPAddress(
            version=tunnel_msg.ue_ipv6_address.version,
            address=addr_str.encode('utf8'),
        )

    if tunnel_msg.enb_ip_address.address:
        enb_ipv4_address = ipaddress.ip_address(
            tunnel_msg.enb_ip_address.address,
        )

    if tunnel_msg.apn:
        apn = tunnel_msg.apn

    return (
        UESessionEntry(
            sid=sid, precedence=tunnel_msg.precedence,
            ue_ipv4_address=ue_ipv4_address,
            ue_ipv6_address=ue_ipv6_address, enb_ip_address=enb_ipv4_address,
            apn=apn, vlan=tunnel_msg.vlan, in_teid=tunnel_msg.in_teid,
            out_teid=tunnel_msg.out_teid,
            ue_session_state=tunnel_msg.ue_session_state.ue_config_state,
            ip_flow_dl=tunnel_msg.ip_flow_dl,
        )
    )
Example #22
0
def _generate_rule_match(imsi, ip_addr, rule_num, version, direction):
    """
    Return a MagmaMatch that matches on the rule num and the version.
    """
    ip_match = get_ue_ip_match_args(ip_addr, direction)

    return MagmaMatch(imsi=encode_imsi(imsi), eth_type=get_eth_type(ip_addr),
                      direction=direction, rule_num=rule_num,
                      rule_version=version, **ip_match)
Example #23
0
    def _delete_resubmit_flow(self, sid, match):
        parser = self._datapath.ofproto_parser
        tbl_num = self._service_manager.get_table_num(self.APP_NAME)

        # Add IMSI metadata
        actions = [
            parser.NXActionRegLoad2(dst=IMSI_REG, value=encode_imsi(sid))
        ]

        flows.delete_flow(self._datapath, tbl_num, match, actions=actions)
Example #24
0
 def get_version(self, imsi: str, rule_id: str) -> int:
     """
     Returns the version number given a subscriber and a rule.
     """
     key = self._get_json_key(encode_imsi(imsi), rule_id)
     with self._lock:
         version = self._version_by_imsi_and_rule.get(key)
         if version is None:
             version = 0
     return version
Example #25
0
    def _install_not_processed_flows(self, datapath, imsi, ip_addr, 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,
                           ipv4_src=ip_addr)
        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,
                           eth_type=ether_types.ETH_TYPE_IP,
                           ipv4_src=ip_addr)
        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,
                                             copy_table=self.stats_table,
                                             resubmit_table=self.next_table)
Example #26
0
    def _deactivate_flows_for_subscriber(self, imsi, _):
        """
        Deactivate all rules for a subscriber, ending any enforcement

        Args:
            imsi (string): subscriber id
        """
        match = MagmaMatch(imsi=encode_imsi(imsi))
        flows.delete_flow(self._datapath, self.tbl_num, match)
        self._redirect_manager.deactivate_flows_for_subscriber(self._datapath,
                                                               imsi)
        self._qos_mgr.remove_subscriber_qos(imsi)
Example #27
0
 def update_version(self, imsi: str, rule_id: Optional[int] = None):
     """
     Increment the version number for a given subscriber and rule. If the
     rule id is not specified, then all rules for the subscriber will be
     incremented.
     """
     with self._lock:
         if rule_id is None:
             for rule in self._version_by_imsi_and_rule[encode_imsi(imsi)]:
                 self._update_version_unsafe(imsi, rule)
         else:
             self._update_version_unsafe(imsi, rule_id)
Example #28
0
    def _install_default_flow_for_subscriber(self, imsi):
        """
        Add a low priority flow to drop a subscriber's traffic in the event
        that all rules have been deactivated.

        Args:
            imsi (string): subscriber id
        """
        match = MagmaMatch(imsi=encode_imsi(imsi))
        actions = []  # empty options == drop
        flows.add_drop_flow(self._datapath, self.tbl_num, match, actions,
                            priority=self.ENFORCE_DROP_PRIORITY)
Example #29
0
    def _delete_resubmit_flow(self, sid, match, action=None):
        parser = self._datapath.ofproto_parser

        if action is None:
            actions = []
        else:
            actions = [action]

        # Add IMSI metadata
        actions.append(
            parser.NXActionRegLoad2(dst=IMSI_REG, value=encode_imsi(sid)))

        flows.delete_flow(self._datapath, self.tbl_num, match, actions=actions)
Example #30
0
    def _ng_tunnel_update(self, pdr_entry: PDRRuleEntry, subscriber_id: str) -> bool:
        if pdr_entry.pdr_state == PdrState.Value('INSTALL'):
            ret = self._classifier_app.add_tunnel_flows(\
                           pdr_entry.precedence, pdr_entry.local_f_teid,\
                           pdr_entry.far_action.o_teid, pdr_entry.ue_ip_addr,\
                           pdr_entry.far_action.gnb_ip_addr, encode_imsi(subscriber_id))

        elif pdr_entry.pdr_state in \
             [PdrState.Value('REMOVE'), PdrState.Value('IDLE')]:
            ret = self._classifier_app.delete_tunnel_flows(\
                           pdr_entry.local_f_teid, pdr_entry.ue_ip_addr)

        return ret