Beispiel #1
0
    def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule):
        """
        Get flow msgs to get stats for a particular rule. Flows will match on
        IMSI, cookie (the rule num), in/out direction

        Args:
            imsi (string): subscriber to install rule for
            msisdn (bytes): subscriber ISDN
            ip_addr (string): subscriber session ipv4 address
            apn_ambr (integer): maximum bandwidth for non-GBR EPS bearers
            rule (PolicyRule): policy rule proto
        """
        rule_num = self._rule_mapper.get_or_create_rule_num(rule.id)
        priority = Utils.get_of_priority(rule.priority)

        flow_adds = []
        for flow in rule.flow_list:
            try:
                version = self._session_rule_version_mapper.get_version(imsi, ip_addr,
                                                                        rule.id)
                flow_adds.extend(self._get_classify_rule_flow_msgs(
                    imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, flow, rule_num, priority,
                    rule.qos, rule.hard_timeout, rule.id, rule.app_name,
                    rule.app_service_type, self.next_service_table,
                    version, self._qos_mgr, self._enforcement_stats_tbl))

            except FlowMatchError as err:  # invalid match
                self.logger.error(
                    "Failed to get flow msg '%s' for subscriber %s: %s",
                    rule.id, imsi, err)
                raise err
        return flow_adds
Beispiel #2
0
    def _add_tunnel_ip_flow_dl(
        self, i_teid: int, ip_flow_dl: IPFlowDL,
        gtp_port: int, o_teid: int, enodeb_ip_addr: str,
        sid: int = None,
    ):

        priority = Utils.get_of_priority(ip_flow_dl.precedence)
        parser = self._datapath.ofproto_parser
        match = self._get_ip_flow_dl_match(ip_flow_dl, self._uplink_port)
        actions = [
            parser.OFPActionSetField(tunnel_id=o_teid),
            parser.OFPActionSetField(tun_ipv4_dst=enodeb_ip_addr),
            parser.NXActionRegLoad2(dst=TUN_PORT_REG, value=gtp_port),
        ]
        if i_teid:
            actions.append(parser.NXActionRegLoad2(dst=INGRESS_TUN_ID_REG, value=i_teid))
        if sid:
            actions.append(parser.OFPActionSetField(metadata=sid))

        flows.add_resubmit_next_service_flow(
            self._datapath, self.tbl_num, match,
            actions=actions, priority=priority,
            reset_default_register=False,
            resubmit_table=self.next_table,
        )

        match = self._get_ip_flow_dl_match(ip_flow_dl, self.config.mtr_port)
        flows.add_resubmit_next_service_flow(
            self._datapath, self.tbl_num, match,
            actions=actions, priority=priority,
            reset_default_register=False,
            resubmit_table=self.next_table,
        )
Beispiel #3
0
    def _resume_tunnel_flows(self, precedence: int, i_teid: int,
                             ue_ip_adr: str):

        priority = Utils.get_of_priority(precedence)
        # Forward flow for gtp port
        match = MagmaMatch(tunnel_id=i_teid, in_port=self.config.gtp_port)

        flows.delete_flow(self._datapath,
                          self.tbl_num,
                          match,
                          priority=priority + 1)

        # Forward flow for LOCAL port
        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                           in_port=self._uplink_port,
                           ipv4_dst=ue_ip_adr)

        flows.delete_flow(self._datapath,
                          self.tbl_num,
                          match,
                          priority=priority + 1)

        # Forward flow for mtr port
        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                           in_port=self.config.mtr_port,
                           ipv4_dst=ue_ip_adr)

        flows.delete_flow(self._datapath,
                          self.tbl_num,
                          match,
                          priority=priority + 1)
Beispiel #4
0
    def _discard_tunnel_flows(self, precedence: int, i_teid: int,
                              ue_ip_adr: IPAddress):

        priority = Utils.get_of_priority(precedence)
        # discard uplink Tunnel
        match = MagmaMatch(tunnel_id=i_teid, in_port=self.config.gtp_port)

        flows.delete_flow(self._datapath,
                          self.tbl_num,
                          match,
                          priority=priority + 1)

        # discard downlink Tunnel for LOCAL port
        ip_match_out = get_ue_ip_match_args(ue_ip_adr, Direction.IN)
        match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                           in_port=self._uplink_port,
                           **ip_match_out)

        flows.delete_flow(self._datapath,
                          self.tbl_num,
                          match,
                          priority=priority + 1)

        match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                           in_port=self.config.mtr_port,
                           **ip_match_out)

        flows.delete_flow(self._datapath,
                          self.tbl_num,
                          match,
                          priority=priority + 1)
Beispiel #5
0
 def _install_redirect_flow(self, imsi, ip_addr, rule, version):
     rule_num = self._rule_mapper.get_or_create_rule_num(rule.id)
     priority = Utils.get_of_priority(rule.priority)
     redirect_request = RedirectionManager.RedirectRequest(
         imsi=imsi,
         ip_addr=ip_addr.address.decode('utf-8'),
         rule=rule,
         rule_num=rule_num,
         rule_version=version,
         priority=priority,
     )
     try:
         self._redirect_manager.setup_lte_redirect(
             self._datapath,
             self.loop,
             redirect_request,
         )
         return RuleModResult.SUCCESS
     except RedirectException as err:
         self.logger.error(
             'Redirect Exception for imsi %s, rule.id - %s : %s',
             imsi,
             rule.id,
             err,
         )
         return RuleModResult.FAILURE
Beispiel #6
0
    def add_s8_tunnel_flows(
        self, precedence: int, i_teid: int,
        o_teid: int, ue_ip_adr: IPAddress,
        enodeb_ip_addr: str, sid: int = None,
        pgw_ip_addr: str = None,
        pgw_gtp_port: int = 0,
        ng_flag: bool = True,
        unused_ue_ipv6_address: IPAddress = None,
        unused_vlan: int = 0,
        ip_flow_dl: IPFlowDL = None,
    ) -> bool:

        priority = Utils.get_of_priority(precedence)
        # Add flow for gtp port
        if enodeb_ip_addr:
            gtp_portno = self._add_gtp_port(enodeb_ip_addr)
        else:
            gtp_portno = self.config.gtp_port

        self._install_uplink_s8_tunnel_flows(
            priority, i_teid, o_teid,
            pgw_ip_addr, gtp_portno, sid, pgw_gtp_port,
        )

        if ip_flow_dl and ip_flow_dl.set_params:
            self._add_tunnel_ip_flow_dl(
                i_teid, ip_flow_dl, gtp_portno, o_teid,
                enodeb_ip_addr, sid,
            )
        else:
            gtp_port = pgw_gtp_port
            if pgw_gtp_port == 0:
                gtp_port = self.config.gtp_port

            if o_teid and enodeb_ip_addr:
                # Add  Downlink Tunnel flow for LOCAL port
                self._install_downlink_tunnel_flows(
                    priority, i_teid, o_teid,
                    gtp_port, ue_ip_adr,
                    enodeb_ip_addr, gtp_portno,
                    sid, ng_flag,
                )

                # Add  Downlink Tunnel flow for mtr port
                self._install_downlink_tunnel_flows(
                    priority, i_teid, o_teid,
                    self.config.mtr_port,
                    ue_ip_adr, enodeb_ip_addr,
                    gtp_portno, sid, ng_flag,
                )

        # Add ARP flow for MTR port
        if ue_ip_adr.version == IPAddress.IPV4:
            # Add ARP flow for mtr port
            self._install_downlink_arp_flows(
                priority, self.config.mtr_port,
                ue_ip_adr, sid,
            )
        return True
Beispiel #7
0
    def _add_tunnel_flows(self, precedence:int, i_teid:int,
                          o_teid:int, ue_ip_adr:str,
                          enodeb_ip_addr:str, sid:int = None):

        parser = self._datapath.ofproto_parser
        priority = Utils.get_of_priority(precedence)
        # Add flow for gtp port
        match = MagmaMatch(tunnel_id=i_teid, in_port=self.config.gtp_port)

        actions = [parser.OFPActionSetField(eth_src=GTP_PORT_MAC),
                   parser.OFPActionSetField(eth_dst="ff:ff:ff:ff:ff:ff")]
        if sid:
            actions.append(parser.OFPActionSetField(metadata=sid))

        flows.add_flow(self._datapath, self.tbl_num, match, actions=actions,
                       priority=priority, goto_table=self.next_table)

        # Add flow for LOCAL port
        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,in_port=self._uplink_port,
                           ipv4_dst=ue_ip_adr)
        actions = [parser.OFPActionSetField(tunnel_id=o_teid),
                   parser.OFPActionSetField(tun_ipv4_dst=enodeb_ip_addr),
                   parser.NXActionRegLoad2(dst=TUN_PORT_REG, value=self.config.gtp_port)]
        if sid:
            actions.append(parser.OFPActionSetField(metadata=sid))

        flows.add_flow(self._datapath, self.tbl_num, match, actions=actions,
                       priority=priority, goto_table=self.next_table)

        # Add flow for mtr port
        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                           in_port=self.config.mtr_port,
                           ipv4_dst=ue_ip_adr)

        flows.add_flow(self._datapath, self.tbl_num, match, actions=actions,
                       priority=priority, goto_table=self.next_table)
       
        # Add ARP flow for LOCAL port
        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_ARP,
                           in_port=self._uplink_port, arp_tpa=ue_ip_adr)
        actions = []
        if sid:
            actions = [parser.OFPActionSetField(metadata=sid)]

        flows.add_flow(self._datapath, self.tbl_num, match, actions=actions,
                       priority=priority, goto_table=self.next_table)

        # Add ARP flow for mtr port
        match = MagmaMatch(eth_type=ether_types.ETH_TYPE_ARP,
                               in_port=self.config.mtr_port,
                               arp_tpa=ue_ip_adr)

        flows.add_flow(self._datapath, self.tbl_num, match, actions=actions,
                       priority=priority, goto_table=self.next_table)
Beispiel #8
0
    def _resume_tunnel_flows(self,
                             precedence: int,
                             i_teid: int,
                             ue_ip_adr: IPAddress = None):
        priority = Utils.get_of_priority(precedence)
        # discard uplink Tunnel
        match = MagmaMatch(tunnel_id=i_teid, in_port=self.config.gtp_port)

        flows.add_resubmit_next_service_flow(self._datapath,
                                             self.tbl_num,
                                             match,
                                             priority=priority + 1,
                                             reset_default_register=False,
                                             resubmit_table=self.next_table)

        # discard downlink Tunnel for LOCAL port
        if not ue_ip_adr:
            self.logger.error("ue_ip_address is None")
            return
        else:
            ip_match_out = get_ue_ip_match_args(ue_ip_adr, Direction.IN)
            match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                               in_port=self._uplink_port,
                               **ip_match_out)

            flows.add_resubmit_next_service_flow(
                self._datapath,
                self.tbl_num,
                match,
                priority=priority + 1,
                reset_default_register=False,
                resubmit_table=self.next_table)

            # discard downlink Tunnel for mtr port
            match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                               in_port=self.config.mtr_port,
                               **ip_match_out)

            flows.add_resubmit_next_service_flow(
                self._datapath,
                self.tbl_num,
                match,
                priority=priority + 1,
                reset_default_register=False,
                resubmit_table=self.next_table)
Beispiel #9
0
    def add_tunnel_flows(self,
                         precedence: int,
                         i_teid: int,
                         o_teid: int,
                         ue_ip_adr: IPAddress,
                         enodeb_ip_addr: str,
                         sid: int = None,
                         ng_flag: bool = True) -> bool:

        priority = Utils.get_of_priority(precedence)
        # Add flow for gtp port
        if enodeb_ip_addr:
            gtp_portno = self._add_gtp_port(enodeb_ip_addr)
        else:
            gtp_portno = self.config.gtp_port

        # Add flow for gtp port for Uplink Tunnel
        if i_teid:
            self._install_uplink_tunnel_flows(priority, i_teid, gtp_portno,
                                              sid)

        if o_teid and enodeb_ip_addr:
            # Add  Downlink Tunnel flow for LOCAL port
            self._install_downlink_tunnel_flows(priority, o_teid,
                                                self._uplink_port, ue_ip_adr,
                                                enodeb_ip_addr, gtp_portno,
                                                sid, ng_flag)

            # Add  Downlink Tunnel flow for mtr port
            self._install_downlink_tunnel_flows(priority, o_teid,
                                                self.config.mtr_port,
                                                ue_ip_adr, enodeb_ip_addr,
                                                gtp_portno, sid, ng_flag)

        # Add ARP flow for LOCAL port
        if ue_ip_adr.version == IPAddress.IPV4:
            # Add ARP flow for LOCAL port
            self._install_downlink_arp_flows(priority, self._uplink_port,
                                             ue_ip_adr, sid)

            # Add ARP flow for mtr port
            self._install_downlink_arp_flows(priority, self.config.mtr_port,
                                             ue_ip_adr, sid)

        return True
Beispiel #10
0
    def _discard_tunnel_flows(self,
                              precedence: int,
                              i_teid: int,
                              ue_ip_adr: IPAddress = None):

        priority = Utils.get_of_priority(precedence)
        # Forward flow for gtp port
        match = MagmaMatch(tunnel_id=i_teid, in_port=self.config.gtp_port)

        flows.delete_flow(self._datapath,
                          self.tbl_num,
                          match,
                          priority=priority + 1)

        # Forward flow for LOCAL port
        if not ue_ip_adr:
            self.logger.error("ue_ip_address is None")
            return
        else:
            ip_match_out = get_ue_ip_match_args(ue_ip_adr, Direction.IN)
            match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                               in_port=self._uplink_port,
                               **ip_match_out)

            flows.delete_flow(self._datapath,
                              self.tbl_num,
                              match,
                              priority=priority + 1)

            match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                               in_port=self.config.mtr_port,
                               **ip_match_out)

            flows.delete_flow(self._datapath,
                              self.tbl_num,
                              match,
                              priority=priority + 1)
Beispiel #11
0
    def add_tunnel_flows(self,
                         precedence: int,
                         i_teid: int,
                         o_teid: int,
                         ue_ip_adr: IPAddress,
                         enodeb_ip_addr: str,
                         sid: int = None) -> bool:

        parser = self._datapath.ofproto_parser
        priority = Utils.get_of_priority(precedence)
        # Add flow for gtp port
        if enodeb_ip_addr:
            gtp_portno = self._add_gtp_port(enodeb_ip_addr)
        else:
            gtp_portno = self.config.gtp_port

        # Add flow for gtp port for Uplink Tunnel
        actions = []
        if i_teid:
            match = MagmaMatch(tunnel_id=i_teid, in_port=gtp_portno)

            actions = [
                parser.OFPActionSetField(eth_src=GTP_PORT_MAC),
                parser.OFPActionSetField(eth_dst="ff:ff:ff:ff:ff:ff")
            ]
            if sid:
                actions.append(parser.OFPActionSetField(metadata=sid))

            flows.add_resubmit_next_service_flow(
                self._datapath,
                self.tbl_num,
                match,
                actions=actions,
                priority=priority,
                reset_default_register=False,
                resubmit_table=self.next_table)

        # Install Downlink Tunnel
        actions = []
        if not ue_ip_adr:
            self.logger.error("ue_ip_address is None")
            return
        else:
            # Add flow for LOCAL port
            ip_match_out = get_ue_ip_match_args(ue_ip_adr, Direction.IN)
            match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                               in_port=self._uplink_port,
                               **ip_match_out)
            if o_teid and enodeb_ip_addr:

                actions = [
                    parser.OFPActionSetField(tunnel_id=o_teid),
                    parser.OFPActionSetField(tun_ipv4_dst=enodeb_ip_addr),
                    parser.OFPActionSetField(tun_flags=TUNNEL_OAM_FLAG),
                    parser.NXActionRegLoad2(dst=TUN_PORT_REG, value=gtp_portno)
                ]
                if sid:
                    actions.append(parser.OFPActionSetField(metadata=sid))

                flows.add_resubmit_next_service_flow(
                    self._datapath,
                    self.tbl_num,
                    match,
                    actions=actions,
                    priority=priority,
                    reset_default_register=False,
                    resubmit_table=self.next_table)

            # Add flow for mtr port
            match = MagmaMatch(eth_type=get_eth_type(ue_ip_adr),
                               in_port=self.config.mtr_port,
                               **ip_match_out)

            flows.add_resubmit_next_service_flow(
                self._datapath,
                self.tbl_num,
                match,
                actions=actions,
                priority=priority,
                reset_default_register=False,
                resubmit_table=self.next_table)

            # Add ARP flow for LOCAL port
            if ue_ip_adr.version == IPAddress.IPV4:
                match = MagmaMatch(eth_type=ether_types.ETH_TYPE_ARP,
                                   in_port=self._uplink_port,
                                   arp_tpa=ipaddress.IPv4Address(
                                       ue_ip_adr.address.decode('utf-8')))
            actions = []
            if sid:
                actions = [parser.OFPActionSetField(metadata=sid)]

            flows.add_resubmit_next_service_flow(
                self._datapath,
                self.tbl_num,
                match,
                actions=actions,
                priority=priority,
                reset_default_register=False,
                resubmit_table=self.next_table)

            # Add ARP flow for mtr port
            if ue_ip_adr.version == IPAddress.IPV4:
                match = MagmaMatch(eth_type=ether_types.ETH_TYPE_ARP,
                                   in_port=self.config.mtr_port,
                                   arp_tpa=ipaddress.IPv4Address(
                                       ue_ip_adr.address.decode('utf-8')))

            flows.add_resubmit_next_service_flow(
                self._datapath,
                self.tbl_num,
                match,
                actions=actions,
                priority=priority,
                reset_default_register=False,
                resubmit_table=self.next_table)

        return True
Beispiel #12
0
    def add_tunnel_flows(
        self,
        precedence: int,
        i_teid: int,
        o_teid: int,
        enodeb_ip_addr: Union[str, IPAddress],
        ue_ip_adr: Optional[IPAddress] = None,
        sid: Optional[int] = None,
        ng_flag: bool = True,
        ue_ipv6_address: Optional[IPAddress] = None,
        unused_apn: Optional[str] = None,
        unused_vlan: int = 0,
        ip_flow_dl: Optional[IPFlowDL] = None,
        session_qfi: QCI = 0,
    ) -> bool:

        priority = Utils.get_of_priority(precedence)
        # Add flow for gtp port
        if enodeb_ip_addr:
            gtp_portno = self._add_gtp_port(enodeb_ip_addr)
        else:
            gtp_portno = self.config.gtp_port

        # Add flow for gtp port for Uplink Tunnel
        if i_teid:
            self._install_uplink_tunnel_flows(
                priority,
                i_teid,
                gtp_portno,
                sid,
                o_teid,
                ng_flag,
                session_qfi,
            )

        if ip_flow_dl and ip_flow_dl.set_params:
            self._add_tunnel_ip_flow_dl(
                i_teid,
                ip_flow_dl,
                gtp_portno,
                o_teid,
                enodeb_ip_addr,
                sid,
            )
        else:
            if o_teid and enodeb_ip_addr:
                # Add  Downlink Tunnel flow for LOCAL port
                self._install_downlink_tunnel_flows(
                    priority,
                    i_teid,
                    o_teid,
                    self._uplink_port,
                    ue_ip_adr,
                    enodeb_ip_addr,
                    gtp_portno,
                    sid,
                    ng_flag,
                    ue_ipv6_address,
                    session_qfi,
                )

                # Add  Downlink Tunnel flow for mtr port
                self._install_downlink_tunnel_flows(
                    priority,
                    i_teid,
                    o_teid,
                    self.config.mtr_port,
                    ue_ip_adr,
                    enodeb_ip_addr,
                    gtp_portno,
                    sid,
                    ng_flag,
                    ue_ipv6_address,
                    session_qfi,
                )

        # Add ARP flow for LOCAL port
        if ue_ip_adr and ue_ip_adr.version == IPAddress.IPV4:
            # Add ARP flow for LOCAL port
            self._install_downlink_arp_flows(
                priority,
                self._uplink_port,
                ue_ip_adr,
                sid,
            )
            # Add ARP flow for mtr port
            self._install_downlink_arp_flows(
                priority,
                self.config.mtr_port,
                ue_ip_adr,
                sid,
            )

        return True
Beispiel #13
0
    def add_tunnel_flows(self,
                         precedence: int,
                         i_teid: int,
                         o_teid: int,
                         ue_ip_adr: str,
                         enodeb_ip_addr: str,
                         sid: int = None) -> bool:

        parser = self._datapath.ofproto_parser
        priority = Utils.get_of_priority(precedence)
        # Add flow for gtp port
        if enodeb_ip_addr:
            gtp_portno = self._add_gtp_port(enodeb_ip_addr)
        else:
            gtp_portno = self.config.gtp_port

        # Add flow for gtp port for Uplink Tunnel
        actions = []
        if i_teid:
            match = MagmaMatch(tunnel_id=i_teid, in_port=gtp_portno)

            actions = [
                parser.OFPActionSetField(eth_src=GTP_PORT_MAC),
                parser.OFPActionSetField(eth_dst="ff:ff:ff:ff:ff:ff")
            ]
            if sid:
                actions.append(parser.OFPActionSetField(metadata=sid))

            flows.add_flow(self._datapath,
                           self.tbl_num,
                           match,
                           actions=actions,
                           priority=priority,
                           goto_table=self.next_table)

        # Install Downlink Tunnel
        actions = []
        if ue_ip_adr:
            if o_teid and enodeb_ip_addr:

                # Add flow for LOCAL port
                match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                                   in_port=self._uplink_port,
                                   ipv4_dst=ue_ip_adr)
                actions = [
                    parser.OFPActionSetField(tunnel_id=o_teid),
                    parser.OFPActionSetField(tun_ipv4_dst=enodeb_ip_addr),
                    parser.OFPActionSetField(tun_flags=TUNNEL_OAM_FLAG),
                    parser.NXActionRegLoad2(dst=TUN_PORT_REG, value=gtp_portno)
                ]
                if sid:
                    actions.append(parser.OFPActionSetField(metadata=sid))

                flows.add_flow(self._datapath,
                               self.tbl_num,
                               match,
                               actions=actions,
                               priority=priority,
                               goto_table=self.next_table)

            # Add flow for mtr port
            match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP,
                               in_port=self.config.mtr_port,
                               ipv4_dst=ue_ip_adr)

            flows.add_flow(self._datapath,
                           self.tbl_num,
                           match,
                           actions=actions,
                           priority=priority,
                           goto_table=self.next_table)

            # Add ARP flow for LOCAL port
            match = MagmaMatch(eth_type=ether_types.ETH_TYPE_ARP,
                               in_port=self._uplink_port,
                               arp_tpa=ue_ip_adr)
            actions = []
            if sid:
                actions = [parser.OFPActionSetField(metadata=sid)]

            flows.add_flow(self._datapath,
                           self.tbl_num,
                           match,
                           actions=actions,
                           priority=priority,
                           goto_table=self.next_table)

            # Add ARP flow for mtr port
            match = MagmaMatch(eth_type=ether_types.ETH_TYPE_ARP,
                               in_port=self.config.mtr_port,
                               arp_tpa=ue_ip_adr)

            flows.add_flow(self._datapath,
                           self.tbl_num,
                           match,
                           actions=actions,
                           priority=priority,
                           goto_table=self.next_table)

        return True