def _install_not_processed_flows(self, datapath, imsi, rule, rule_num, priority): """ Redirect all traffic to the scratch table to only allow redirected http traffic to go through, the rest will be dropped. reg0 is used as a boolean to know whether the drop rule was processed. """ parser = datapath.ofproto_parser of_note = parser.NXActionNote(list(rule.id.encode())) match = MagmaMatch(imsi=encode_imsi(imsi), direction=Direction.OUT, reg0=self.REDIRECT_NOT_PROCESSED, eth_type=ether_types.ETH_TYPE_IP) action = [of_note] flows.add_resubmit_current_service_flow( datapath, self.main_tbl_num, match, action, priority=priority, cookie=rule_num, hard_timeout=rule.hard_timeout, resubmit_table=self._scratch_tbl_num) match = MagmaMatch(imsi=encode_imsi(imsi), direction=Direction.OUT, reg0=self.REDIRECT_PROCESSED) action = [of_note] flows.add_resubmit_next_service_flow( datapath, self.main_tbl_num, match, action, priority=priority, cookie=rule_num, hard_timeout=rule.hard_timeout, resubmit_table=self.next_table)
def _install_scratch_table_flows(self, datapath, imsi, rule, rule_num, rule_version, priority): """ The flow action for subscribers that need to be redirected does 2 things * Forward requests from subscriber to the internal http server * Instantiate a flow that matches response packets from the server and sends them back to subscriber Match: incoming tcp traffic with port 80, direction out Action: 1) Set reg2 to rule_num 2) Set ip dst to server ip 3) Output to table 20 4) Apply LearnAction: LearnAction(adds new flow for every pkt flow that hits this rule) 1) Match ip packets 2) Match tcp protocol 3) Match packets from LOCAL port 4) Match ip src = server ip 5) Match ip dst = current flow ip src 6) Match tcp src = current flow tcp dst 7) Match tcp dst = current flow tcp src 8) Load ip src = current flow ip dst 9) Output through gtp0 """ parser = datapath.ofproto_parser match_http = MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, ip_proto=IPPROTO_TCP, tcp_dst=80, imsi=encode_imsi(imsi), direction=Direction.OUT) of_note = parser.NXActionNote(list(rule.id.encode())) actions = [ parser.NXActionLearn( table_id=self.main_tbl_num, priority=priority, cookie=rule_num, specs=[ parser.NXFlowSpecMatch(src=ether_types.ETH_TYPE_IP, dst=('eth_type_nxm', 0), n_bits=16), parser.NXFlowSpecMatch(src=IPPROTO_TCP, dst=('ip_proto_nxm', 0), n_bits=8), parser.NXFlowSpecMatch(src=Direction.IN, dst=(DIRECTION_REG, 0), n_bits=32), parser.NXFlowSpecMatch(src=int( ipaddress.IPv4Address(self._bridge_ip)), dst=('ipv4_src_nxm', 0), n_bits=32), parser.NXFlowSpecMatch(src=('ipv4_src_nxm', 0), dst=('ipv4_dst_nxm', 0), n_bits=32), parser.NXFlowSpecMatch(src=('tcp_src_nxm', 0), dst=('tcp_dst_nxm', 0), n_bits=16), parser.NXFlowSpecMatch(src=self._redirect_port, dst=('tcp_src_nxm', 0), n_bits=16), parser.NXFlowSpecMatch(src=encode_imsi(imsi), dst=(IMSI_REG, 0), n_bits=64), parser.NXFlowSpecLoad(src=('ipv4_dst_nxm', 0), dst=('ipv4_src_nxm', 0), n_bits=32), parser.NXFlowSpecLoad(src=80, dst=('tcp_src_nxm', 0), n_bits=16), # Learn doesn't support resubmit to table, so send directly parser.NXFlowSpecOutput(src=('in_port', 0), dst="", n_bits=16), ]), parser.NXActionRegLoad2(dst=SCRATCH_REGS[0], value=self.REDIRECT_PROCESSED), parser.OFPActionSetField(ipv4_dst=self._bridge_ip), parser.OFPActionSetField(tcp_dst=self._redirect_port), of_note, ] actions += self._load_rule_actions(parser, rule_num, rule_version) flows.add_resubmit_current_service_flow( datapath, self._scratch_tbl_num, match_http, actions, priority=priority, cookie=rule_num, hard_timeout=rule.hard_timeout, resubmit_table=self.main_tbl_num) match = MagmaMatch(imsi=encode_imsi(imsi)) action = [] flows.add_drop_flow(datapath, self._scratch_tbl_num, match, action, priority=flows.MINIMUM_PRIORITY + 1, cookie=rule_num)