def add_classify_flow(self, flow_match, flow_state, app: str, service_type: str): """ Parse DPI output and set the register for future packets matching this flow. APP is split into tokens as the top level app is not supported, but the parent protocol might be. Example we care about google traffic, but don't neccessarily want to classify every specific google service. """ # TODO add error return if self._datapath is None: return parser = self._datapath.ofproto_parser app_id = get_app_id(app, service_type) 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 actions = [parser.NXActionRegLoad2(dst=DPI_REG, value=app_id)] # No reason to create a flow here if flow_state != FlowRequest.FLOW_CREATED: flows.add_flow(self._datapath, self._classify_app_tbl_num, ul_match, actions, priority=flows.DEFAULT_PRIORITY, idle_timeout=self._idle_timeout) flows.add_flow(self._datapath, self._classify_app_tbl_num, dl_match, actions, priority=flows.DEFAULT_PRIORITY, idle_timeout=self._idle_timeout)
def add_classify_flow(self, flow_match, app: str, service_type: str, src_mac: str, dst_mac: str): """ Parse DPI output and set the register for future packets matching this flow. APP is split into tokens as the top level app is not supported, but the parent protocol might be. Example we care about google traffic, but don't neccessarily want to classify every specific google service. """ parser = self._datapath.ofproto_parser app_id = self._get_app_id(app, service_type) 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 actions = [parser.NXActionRegLoad2(dst=DPI_REG, value=app_id)] actions_w_mirror = \ [parser.OFPActionOutput(self._mon_port_number)] + actions flows.add_resubmit_next_service_flow(self._datapath, self.tbl_num, ul_match, actions_w_mirror, priority=flows.DEFAULT_PRIORITY, resubmit_table=self.next_table, idle_timeout=self._idle_timeout) flows.add_resubmit_next_service_flow(self._datapath, self.tbl_num, dl_match, actions_w_mirror, priority=flows.DEFAULT_PRIORITY, resubmit_table=self.next_table, idle_timeout=self._idle_timeout) if self._service_manager.is_app_enabled(IPFIXController.APP_NAME): self._generate_ipfix_sampling_pkt(flow_match, src_mac, dst_mac) flows.add_resubmit_next_service_flow( self._datapath, self._app_set_tbl_num, ul_match, actions, priority=flows.DEFAULT_PRIORITY, resubmit_table=self._imsi_set_tbl_num, idle_timeout=self._idle_timeout) flows.add_resubmit_next_service_flow( self._datapath, self._app_set_tbl_num, dl_match, actions, priority=flows.DEFAULT_PRIORITY, resubmit_table=self._imsi_set_tbl_num, idle_timeout=self._idle_timeout)
def remove_classify_flow(self, flow_match): 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) return True
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 add_classify_flow(self, flow_match, app: str, service_type: str): """ Parse DPI output and set the register for future packets matching this flow. APP is split into tokens as the top level app is not supported, but the parent protocol might be. Example we care about google traffic, but don't neccessarily want to classify every specific google service. """ parser = self._datapath.ofproto_parser tokens = app.split('.') # We could be sent an app that we don't care about, just ignore it if not any(app for app in tokens if app in PARENT_PROTOS or app in APP_PROTOS): self.logger.debug("Unrecognized app name %s", app) return app_match = [app for app in tokens if app in APP_PROTOS] if len(app_match) > 1: self.logger.warning("Found more than 1 app match in %s", app) return if (len(app_match) == 1): app_id = APP_PROTOS[app_match[0]] self.logger.debug("Classified %s-%s as %d", app, service_type, app_id) else: parent_match = [app for app in tokens if app in PARENT_PROTOS] # This shoudn't happen as we confirmed the match exists if len(parent_match) == 0: self.logger.warning("Didn't find a match for app name %s", app) return if len(parent_match) > 1: self.logger.warning("Found more than 1 parent app match in %s", app) app_id = PARENT_PROTOS[parent_match[0]] service_id = SERVICE_IDS['other'] for serv in SERVICE_IDS: if serv in service_type.lower(): service_id = SERVICE_IDS[serv] break app_id += service_id self.logger.error("Classified %s-%s as %d", app, service_type, app_id) 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 actions = [ parser.OFPActionOutput(self._mon_port_number), parser.NXActionRegLoad2(dst=DPI_REG, value=app_id) ] flows.add_resubmit_next_service_flow(self._datapath, self.tbl_num, ul_match, actions, priority=flows.DEFAULT_PRIORITY, resubmit_table=self.next_table, idle_timeout=self._idle_timeout) flows.add_resubmit_next_service_flow(self._datapath, self.tbl_num, dl_match, actions, priority=flows.DEFAULT_PRIORITY, resubmit_table=self.next_table, idle_timeout=self._idle_timeout)