def remove_classify_flow(self, flow_match, src_mac: str, dst_mac: str): try: ul_match = flow_match_to_magma_match(flow_match) ul_match.direction = None dl_match = flow_match_to_magma_match(flip_flow_match(flow_match)) dl_match.direction = None except FlowMatchError as e: self.logger.error(e) return False flows.delete_flow(self._datapath, self.tbl_num, ul_match) flows.delete_flow(self._datapath, self.tbl_num, dl_match) if self._service_manager.is_app_enabled(IPFIXController.APP_NAME): self._generate_ipfix_sampling_pkt(flow_match, src_mac, dst_mac) return True
def _deactivate_flow_for_rule(self, imsi, 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 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) self._qos_mgr.remove_subscriber_qos(imsi, num)
def _deactivate_flows_for_subscriber(self, imsi, ip_addr): """ Deactivate all rules for specified subscriber session """ ip_match_in = get_ue_ipv4_match_args(ip_addr, Direction.IN) match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, imsi=encode_imsi(imsi), **ip_match_in) flows.delete_flow(self._datapath, self.tbl_num, match) ip_match_out = get_ue_ipv4_match_args(ip_addr, Direction.OUT) match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, 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)
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)
def _discard_tunnel_ip_flow_dl(self, ip_flow_dl: IPFlowDL): match = self._get_ip_flow_dl_match(ip_flow_dl, self._uplink_port) flows.delete_flow( self._datapath, self.tbl_num, match, priority=Utils.DISCARD_RULE_PRIORITY, ) match = self._get_ip_flow_dl_match(ip_flow_dl, self.config.mtr_port) flows.delete_flow( self._datapath, self.tbl_num, match, priority=Utils.DISCARD_RULE_PRIORITY, )
def _deactivate_flows_for_subscriber(self, imsi, ip_addr): """ Deactivate all rules for a subscriber, ending any enforcement Args: imsi (string): subscriber id ip_addr(IPAddress): session IP address """ 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, ) if self._qos_mgr: self._qos_mgr.remove_subscriber_qos(imsi) self._remove_he_flows(ip_addr, "")
def delete_ue_sample_flow(self, imsi: str) -> None: """ Delete a flow to sample packets for IPFIX for specific imsi Args: imsi (string): subscriber to install rule for """ if self._datapath is None: self.logger.error('Datapath not initialized') return if not imsi: self.logger.error('No subscriber specified') return match = MagmaMatch(imsi=encode_imsi(imsi)) flows.delete_flow(self._datapath, self.tbl_num, match)
def delete_tunnel_flows(self, i_teid: int, ue_ip_adr: str, enodeb_ip_addr: str = None) -> bool: # Delete flow for gtp port if enodeb_ip_addr: gtp_portno = self._add_gtp_port(enodeb_ip_addr) else: gtp_portno = self.config.gtp_port if i_teid: match = MagmaMatch(tunnel_id=i_teid, in_port=gtp_portno) flows.delete_flow(self._datapath, self.tbl_num, match) # Delete flow for LOCAL port if ue_ip_adr: 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) # Delete 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) # Delete ARP flow for LOCAL port match = MagmaMatch(eth_type=ether_types.ETH_TYPE_ARP, in_port=self._uplink_port, arp_tpa=ue_ip_adr) flows.delete_flow(self._datapath, self.tbl_num, match) # Delete 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.delete_flow(self._datapath, self.tbl_num, match) return True
def _delete_flow(self, imsi, ip_addr, rule_id, rule_version): rule_num = self._rule_mapper.get_or_create_rule_num(rule_id) cookie, mask = (rule_num, flows.OVS_COOKIE_MATCH_ALL) match_in = _generate_rule_match(imsi, ip_addr, cookie, rule_version, Direction.IN) match_out = _generate_rule_match(imsi, ip_addr, cookie, rule_version, Direction.OUT) flows.delete_flow(self._datapath, self.tbl_num, match_in, cookie=cookie, cookie_mask=mask) flows.delete_flow(self._datapath, self.tbl_num, match_out, cookie=cookie, cookie_mask=mask)
def deactivate_rules(self, imsi: str) -> None: """ Deactivate flows for a subscriber. Args: imsi (string): subscriber id """ if self._datapath is None: self.logger.error('Datapath not initialized') return if not imsi: self.logger.error('No subscriber specified') return match = MagmaMatch(imsi=encode_imsi(imsi)) flows.delete_flow(self._datapath, self.tbl_num, match)
def _delete_dhcp_passthrough_flows(self, sid, mac_addr): parser = 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._delete_resubmit_flow(sid, uplink_match, action) downlink_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, ip_proto=IPPROTO_UDP, udp_src=67, udp_dst=68, eth_dst=mac_addr) self._delete_resubmit_flow(sid, downlink_match, action) imsi_match = MagmaMatch(imsi=encode_imsi(sid)) flows.delete_flow(self._datapath, self._dhcp_learn_scratch, imsi_match)
def _delete_dhcp_passthrough_flows(self, sid, mac_addr): parser = self._datapath.ofproto_parser # Set so inout knows to skip tables and send to egress action = load_direction(parser, Direction.PASSTHROUGH) 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._delete_resubmit_flow(sid, uplink_match, action) downlink_match = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, ip_proto=IPPROTO_UDP, udp_src=67, udp_dst=68, eth_dst=mac_addr) self._delete_resubmit_flow(sid, downlink_match, action) imsi_match = MagmaMatch(imsi=encode_imsi(sid)) flows.delete_flow(self._datapath, self._dhcp_learn_scratch, imsi_match)
def _delete_downlink_tunnel_flows(self, ue_ip_adr: IPAddress, in_port: int, ue_ipv6_adr: IPAddress = None): if ue_ip_adr: 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=in_port, **ip_match_out, ) flows.delete_flow(self._datapath, self.tbl_num, match) if ue_ipv6_adr: ip_match_out = get_ue_ip_match_args(ue_ipv6_adr, Direction.IN) match = MagmaMatch( eth_type=get_eth_type(ue_ipv6_adr), in_port=in_port, **ip_match_out, ) flows.delete_flow(self._datapath, self.tbl_num, match)
def discard_tunnel_flows(self, i_teid: int, ue_ip_adr: IPAddress, ip_flow_dl: IPFlowDL = None): # discard 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=Utils.DISCARD_RULE_PRIORITY) if ip_flow_dl and ip_flow_dl.set_params: self._discard_tunnel_ip_flow_dl(ip_flow_dl) else: # 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=Utils.DISCARD_RULE_PRIORITY) 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=Utils.DISCARD_RULE_PRIORITY) return True
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)
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)
def remove_subscriber_he_flows(self, ue_addr: IPAddress, rule_num: int = -1): """ Remove proxy flows of give policy rule of the subscriber. Args: ue_addr(str): IP address of UE rule_num(int): rule num of the policy rule """ logging.info("Del HE rule: ue-ip: %s rule %d", ue_addr, rule_num) ue_ip_str = ipv4_address_to_str(ue_addr) if ue_ip_str not in self._he_enabled_ue_ips: return if rule_num == -1: ip_match_in = get_ue_ip_match_args(ue_addr, Direction.IN) match_in = MagmaMatch(eth_type=get_eth_type(ue_addr), **ip_match_in) flows.delete_flow(self._datapath, self.tbl_num, match_in) ip_match_out = get_ue_ip_match_args(ue_addr, Direction.OUT) match_out = MagmaMatch(eth_type=get_eth_type(ue_addr), **ip_match_out) flows.delete_flow(self._datapath, self.tbl_num, match_out) else: match = MagmaMatch() flows.delete_flow(self._datapath, self.tbl_num, match, cookie=rule_num, cookie_mask=flows.OVS_COOKIE_MATCH_ALL) deactivate_he_urls_for_ue(ue_addr) self._he_enabled_ue_ips.remove(ue_ip_str)
def remove_subscriber_flow(self, ue_addr: IPAddress, rule_num: int = -1): """ Remove proxy flows of give policy rule of the subscriber. Args: ue_addr(str): IP address of UE rule_num(int): rule num of the policy rule """ logging.info("Del he rule: ue-ip: %s rule %d", ue_addr, rule_num) # self.set_he_target_urls(ue_addr, ip_dst, urls, imsi, msisdn) if rule_num == -1: ip_match_in = get_ue_ip_match_args(ue_addr, Direction.IN) match_in = MagmaMatch(eth_type=get_eth_type(ue_addr), **ip_match_in) flows.delete_flow(self._datapath, self.tbl_num, match_in) ip_match_out = get_ue_ip_match_args(ue_addr, Direction.OUT) match_out = MagmaMatch(eth_type=get_eth_type(ue_addr), **ip_match_out) flows.delete_flow(self._datapath, self.tbl_num, match_out) else: match = MagmaMatch() flows.delete_flow(self._datapath, self.tbl_num, match, cookie=rule_num, cookie_mask=flows.OVS_COOKIE_MATCH_ALL)
def deactivate_default_flow(self, imsi, ip_addr, local_f_teid_ng=0): if self._datapath is None: self.logger.error('Datapath not initialized') return match_in = _generate_rule_match( imsi, ip_addr, 0, 0, Direction.IN, local_f_teid_ng, ) match_out = _generate_rule_match( imsi, ip_addr, 0, 0, Direction.OUT, local_f_teid_ng, ) flows.delete_flow(self._datapath, self.tbl_num, match_in) flows.delete_flow(self._datapath, self.tbl_num, match_out)
def remove_subscriber_he_flows( self, ue_addr: IPAddress, rule_id: str = "", rule_num: int = -1, ): """ Remove proxy flows of give policy rule of the subscriber. Args: ue_addr(str): IP address of UE rule_id(str) Rule id rule_num(int): rule num of the policy rule """ ue_ip_str = ipv4_address_to_str(ue_addr) if self._ue_rule_counter.get(ue_ip_str) == 0: return logging.info( "Del HE rule: ue-ip: %s rule_id: %s rule %d", ue_addr, rule_id, rule_num, ) if rule_num == -1: ip_match_in = get_ue_ip_match_args(ue_addr, Direction.IN) match_in = MagmaMatch( eth_type=get_eth_type(ue_addr), **ip_match_in, ) flows.delete_flow(self._datapath, self.tbl_num, match_in) ip_match_out = get_ue_ip_match_args(ue_addr, Direction.OUT) match_out = MagmaMatch( eth_type=get_eth_type(ue_addr), **ip_match_out, ) flows.delete_flow(self._datapath, self.tbl_num, match_out) else: match = MagmaMatch() flows.delete_flow( self._datapath, self.tbl_num, match, cookie=rule_num, cookie_mask=flows.OVS_COOKIE_MATCH_ALL, ) success = deactivate_he_urls_for_ue(ue_addr, rule_id) logging.debug("Del HE proxy: %s", success) if success: if rule_num == -1: self._ue_rule_counter.delete(ue_ip_str) else: self._ue_rule_counter.dec(ue_ip_str)
def _remove_subscriber_flow(self, imsi: str): match = MagmaMatch(imsi=encode_imsi(imsi), eth_type=ether_types.ETH_TYPE_IP, ip_proto=IPPROTO_TCP, direction=Direction.OUT, ipv4_dst=self.config.quota_check_ip) flows.delete_flow(self._datapath, self.tbl_num, match) 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) flows.delete_flow(self._datapath, self.tbl_num, match) 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) flows.delete_flow(self._datapath, self.tbl_num, match)
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)
def deactivate_default_flow(self, imsi, ip_addr): match_in = _generate_rule_match(imsi, ip_addr, 0, 0, Direction.IN) match_out = _generate_rule_match(imsi, ip_addr, 0, 0, Direction.OUT) flows.delete_flow(self._datapath, self.tbl_num, match_in) flows.delete_flow(self._datapath, self.tbl_num, match_out)
def _remove_mirror_flows(self, imsis): for imsi in imsis: self.logger.error("Disabling LI tracking for IMSI %s", imsi) match = MagmaMatch(imsi=encode_imsi(imsi)) flows.delete_flow(self._datapath, self.tbl_num, match)
def _delete_tunnel_ip_flow_dl(self, ip_flow_dl: IPFlowDL): match = self._get_ip_flow_dl_match(ip_flow_dl, self._uplink_port) flows.delete_flow(self._datapath, self.tbl_num, match) match = self._get_ip_flow_dl_match(ip_flow_dl, self.config.mtr_port) flows.delete_flow(self._datapath, self.tbl_num, match)
def _delete_uplink_tunnel_flows(self, i_teid: int, gtp_portno: int): match = MagmaMatch(tunnel_id=i_teid, in_port=gtp_portno) flows.delete_flow(self._datapath, self.tbl_num, match)
def _delete_meter_flows(self, deleted_subs): for _, datapath in self.dpset.get_all(): for imsi in deleted_subs: match = MagmaMatch(imsi=encode_imsi(imsi)) for table in self.table_nums: flows.delete_flow(datapath, table, match)
def remove_subscriber_flow(self, imsi: str): match = MagmaMatch(imsi=encode_imsi(imsi)) flows.delete_flow(self._datapath, self.tbl_num, match) flows.delete_flow(self._datapath, self.ip_rewrite_scratch, match)
def remove_subscriber_flow(self, imsi: str): match = MagmaMatch(imsi=encode_imsi(imsi)) flows.delete_flow(self._datapath, self.vlan_id_scratch, match) flows.delete_flow(self._datapath, self.vlan_header_scratch, match)
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)))