def Main(args): defs.DOL_PATH = "/iota/" defs.TEST_TYPE = "IOTA" EzAccessStore.SetTestbedSpec(api.GetTestbedSpec()) for node, cfgyml in vars(args.spec).items(): api.Logger.info(f"Generating Configuration for Spec {cfgyml}") cfgspec = parser.ParseFile('test/apulu/config/cfg/', f'{cfgyml}') naples_uuid_map = api.GetNaplesNodeUuidMap() EzAccessStoreInit(node) EzAccessStore.SetUuidMap(naples_uuid_map) EzAccessStoreClient[node].SetUnderlayIPs(api.GetNicUnderlayIPs(node)) NodeClient.CreateNode(node, cfgspec, api.GetNicMgmtIP(node)) if not __generate_rmappings_from_lmappings(): api.Logger.error("Failed to convert local mappings to remote mappings") return api.types.status.FAILURE # Update static NextHop objects with the mac-addresses of the peer's interfaces # This is temporary until the dynamic underlay NH stitching support comes in soon. __update_nexthops_from_uplink_info() __update_host_interfaces() naplesNodes = api.GetNaplesHostnames() MemStatsClient.InitNodesForMemUsageStats(naplesNodes) for node in naplesNodes: storeClient = EzAccessStoreClient[node] if storeClient.IsDeviceLearningEnabled(): if not learn_utils.SetDeviceLearnTimeout(storeClient.GetDevice().GetLearnAgeTimeout()): return api.types.status.FAILURE if not learn_utils.ClearLearnData(): return api.types.status.FAILURE return api.types.status.SUCCESS
def initialize_object_info(): logger.info("Initializing object info") ObjectInfo[APIObjTypes.DEVICE.name.lower()] = DeviceClient ObjectInfo[APIObjTypes.TUNNEL.name.lower()] = TunnelClient ObjectInfo[APIObjTypes.INTERFACE.name.lower()] = InterfaceClient ObjectInfo[APIObjTypes.NEXTHOP.name.lower()] = NexthopClient ObjectInfo[APIObjTypes.NEXTHOPGROUP.name.lower()] = NHGroupClient ObjectInfo[APIObjTypes.VPC.name.lower()] = VpcClient ObjectInfo[APIObjTypes.SUBNET.name.lower()] = SubnetClient ObjectInfo[APIObjTypes.VNIC.name.lower()] = VnicClient ObjectInfo[APIObjTypes.LMAPPING.name.lower()] = LmappingClient ObjectInfo[APIObjTypes.RMAPPING.name.lower()] = RmappingClient ObjectInfo[APIObjTypes.ROUTE.name.lower()] = RouteTableClient ObjectInfo[APIObjTypes.POLICY.name.lower()] = PolicyClient ObjectInfo[ APIObjTypes.SECURITY_PROFILE.name.lower()] = SecurityProfileClient ObjectInfo[APIObjTypes.MIRROR.name.lower()] = MirrorClient ObjectInfo[APIObjTypes.METER.name.lower()] = MeterClient ObjectInfo[APIObjTypes.TAG.name.lower()] = TagClient ObjectInfo[APIObjTypes.DHCP_RELAY.name.lower()] = DHCPRelayClient ObjectInfo[APIObjTypes.DHCP_PROXY.name.lower()] = DHCPProxyClient ObjectInfo[APIObjTypes.NAT.name.lower()] = NATPbClient ObjectInfo[APIObjTypes.POLICER.name.lower()] = PolicerClient ObjectInfo[APIObjTypes.BGP.name.lower()] = BGPClient ObjectInfo[APIObjTypes.BGP_PEER.name.lower()] = BGPPeerClient ObjectInfo[APIObjTypes.BGP_PEER_AF.name.lower()] = BGPPeerAfClient ObjectInfo[APIObjTypes.BGP_EVPN_EVI.name.lower()] = EvpnEviClient ObjectInfo[APIObjTypes.BGP_EVPN_EVI_RT.name.lower()] = EvpnEviRtClient ObjectInfo[APIObjTypes.BGP_EVPN_IP_VRF.name.lower()] = EvpnIpVrfClient ObjectInfo[APIObjTypes.BGP_EVPN_IP_VRF_RT.name.lower()] = EvpnIpVrfRtClient EzAccessStore.SetConfigClientDict(ObjectInfo)
def GenerateObjects(self, node, vpcid, topospec=None): def __add_dhcp_relay_config(node, dhcpobj): obj = DhcpRelayObject(node, vpcid, dhcpobj) self.Objs[node].update({obj.Id: obj}) dhcprelaySpec = None if topospec: dhcprelaySpec = getattr(topospec, 'dhcprelay', None) if not dhcprelaySpec: tbSpec = EzAccessStore.GetTestbedSpec() dhcprelaySpec = getattr(tbSpec, 'DHCPRelay', None) if dhcprelaySpec: for obj in dhcprelaySpec: attrb = copy.copy(vars(obj)) for key, val in attrb.items(): setattr(obj, key.lower(), val) else: return # In netagent-IOTA mode, there is a single IPAM-Policy with all server/relay # configs, which netagent will break down to individual PDS-agent gRPC objects __add_dhcp_relay_config(node, dhcprelaySpec) EzAccessStoreClient[node].SetDhcpRelayObjects(self.Objects(node)) ResmgrClient[node].CreateDHCPRelayAllocator() return
def GetMatchingConfigObjects(self, selectors): objs = [] fwdmode = None mapsel = selectors key = 'FwdMode' # Consider it only if TEST is for MAPPING if mapsel.flow.GetValueByKey('FlType') != 'MAPPING': return objs # Get the forwarding mode, fwdmode is not applicable for local & remote fwdmode = mapsel.flow.GetValueByKey(key) mapsel.flow.filters.remove((key, fwdmode)) rmapsel = copy.deepcopy(mapsel) assert (fwdmode == 'VNET' or fwdmode == 'IGW' or fwdmode == 'SVCTUN' or\ fwdmode == 'SVCTUN_REMOTE') == True dutNode = EzAccessStore.GetDUTNode() if fwdmode == 'VNET': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): for robj in rmapping.GetMatchingObjects(rmapsel, dutNode): # Ignore VPC-ID 1 , Reserved for substrate if lobj.VNIC.SUBNET.VPC.VPCId == 1 or robj.SUBNET.VPC.VPCId == 1: continue if lobj.VNIC.SUBNET.VPC.VPCId != robj.SUBNET.VPC.VPCId: continue obj = FlowMapObject(lobj, robj, fwdmode, None) objs.append(obj) return utils.GetFilteredObjects(objs, selectors.maxlimits) elif fwdmode == 'IGW': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): for routetblobj in routetable.GetAllMatchingObjects(mapsel): if not self.__is_lmapping_match(routetblobj, lobj): continue obj = FlowMapObject(lobj, None, fwdmode, routetblobj) objs.append(obj) return utils.GetFilteredObjects(objs, selectors.maxlimits) elif fwdmode == 'SVCTUN' or fwdmode == 'SVCTUN_REMOTE': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): vpc = lobj.VNIC.SUBNET.VPC if vpc.Nat46_pfx is not None: for routetblobj in routetable.GetAllMatchingObjects( mapsel): if fwdmode == 'SVCTUN_REMOTE': if routetblobj.TUNNEL.Remote is False: continue obj = FlowMapObject(lobj, None, fwdmode, routetblobj) objs.append(obj) return utils.GetFilteredObjects(objs, selectors.maxlimits) else: assert 0
def __is_matching_dst_ip(dst_ip, l3matchobj, direction, testcase): dutNode = EzAccessStore.GetDUTNode() v4ltags, v6ltags, v4rtags, v6rtags = utils.GetTagsFromMapping(dutNode) af = testcase.config.localmapping.AddrFamily if utils.IsPipelineApulu() and (l3matchobj.DstType == topo.L3MatchType.TAG): if direction == "ingress": if af == 'IPV4': for obj in v4ltags[l3matchobj.DstTag]: if str(dst_ip) == obj.IP: return True else: for obj in v6ltags[l3matchobj.DstTag]: if str(dst_ip) == obj.IP: return True else: if af == 'IPV4': for obj in v4rtags[l3matchobj.DstTag]: if str(dst_ip) == obj.IP: return True else: for obj in v6rtags[l3matchobj.DstTag]: if str(dst_ip) == obj.IP: return True return False return __is_matching_ip(l3matchobj.DstType, dst_ip, l3matchobj.DstPrefix, l3matchobj.DstIPLow, l3matchobj.DstIPHigh, l3matchobj.DstTag)
def __init__(self): self.DevObject = EzAccessStoreClient[ EzAccessStore.GetDUTNode()].GetDevice() self.PreStats = DropStats() self.PostStats = DropStats() self.ExpStats = None return
def GetMeterStats(self): grpcmsg = meter_pb2.MeterGetRequest() if self.MeterId != None: grpcmsg.Id = self.MeterId resp = api.client[EzAccessStore.GetDUTNode()].Get(api.ObjectTypes.METER, [ grpcmsg ]) if resp != None: return resp[0] return None
def TestCaseVerify(tc): if 'WORKFLOW_START' in tc.module.name: topo.ChosenFlowObjs.select_objs = False topo.ChosenFlowObjs.use_selected_objs = True elif 'WORKFLOW_END' in tc.module.name: topo.ChosenFlowObjs.Reset() NodeClient.Read(EzAccessStore.GetDUTNode()) return True
def Main(): topospec = __get_topo_spec() # TODO: Fix topos to have node name # Add node class dutnode = "Node%d" % topospec.dutnode EzAccessStore.SetDUTNode(dutnode) for nodespec in topospec.node: nodename = "Node%d" % nodespec.id NodeClient.CreateNode(nodename, nodespec) return
def GetMatchingConfigObjects(self, selectors): objs = [] dutNode = EzAccessStore.GetDUTNode() policyobjs = filter(lambda x: x.IsFilterMatch(selectors), policy.client.Objects(dutNode)) for policyObj in policyobjs: for lobj in lmapping.client.Objects(dutNode): if self.__is_lmapping_match(policyObj, lobj): policyObj.l_obj = lobj objs.append(policyObj) break return utils.GetFilteredObjects(objs, selectors.maxlimits, False)
def __init__(self, lobj, robj, fwdmode, routeobj): super().__init__() self.Node = EzAccessStore.GetDUTNode() self.Clone(EzAccessStore.templates.Get('FLOW')) self.FlowMapId = next(ResmgrClient[self.Node].FlowIdAllocator) self.GID('FlowMap%d' % self.FlowMapId) self.FwdMode = fwdmode self.__lobj = lobj self.__robj = robj self.__dev = EzAccessStoreClient[self.Node].GetDevice() self.__routeobj = routeobj self.Show() return
def __init__(self, node, topospec, ip=None): super().__init__(topo.ObjectTypes.NODE, node) self.Node = node self.__topospec = topospec self.__connected = False self.ReconfigState = ReconfigState() self.NodeType = None if self.Node == EzAccessStore.GetDUTNode(): self.NodeType = 'DUT' agentapi.Init(node, ip) resmgr.Init(node) store.Init(node, self) if not utils.IsDol(): EzAccessStoreClient[self.Node].NodeObj = self
def SetupTestcaseConfig(self, obj): obj.root = self obj.localmapping = self.__lobj obj.remotemapping = self.__robj obj.route = self.__routeTblObj obj.tunnel = self.__tunobj obj.devicecfg = self.__dev #TODO: Handle host mode obj.hostport = EzAccessStoreClient[self.Node].GetHostPort() obj.switchport = EzAccessStoreClient[self.Node].GetSwitchPort() obj.dhcprelay = dhcprelay.client.GetDhcpRelayObject( EzAccessStore.GetDUTNode()) obj.securityprofile = EzAccessStoreClient[ self.Node].GetSecurityProfile() utils.DumpTestcaseConfig(obj) return
def UpdatePolicer(tc, workload): if not workload.IsNaples(): return 0 PolicerClient = EzAccessStore.GetConfigClient( agent_api.ObjectTypes.POLICER) policer = PolicerClient.GetMatchingPolicerObject(workload.node_name,\ tc.iterators.direction, tc.iterators.policertype) if policer: spec = PolicerUpdateSpec(policer) workload.vnic.Update(spec) tokens = ((policer.rate * tc.duration) + policer.burst) vnic_id = workload.vnic.UUID.String() pdsctl.ExecutePdsctlCommand(workload.node_name,\ f"clear vnic statistics -i {vnic_id}", None, yaml=False) else: tokens = 0 return tokens
def GetMatchingConfigObjects(self, selectors, all_objs): objs = [] rtype = selectors.route.GetValueByKey('RouteType') dutNode = EzAccessStore.GetDUTNode() for route_obj in route.client.Objects(dutNode): if not route_obj.IsFilterMatch(selectors): continue if rtype != 'empty' and 0 == len(route_obj.routes): # skip route tables with no routes continue for lobj in lmapping.GetMatchingObjects(selectors, dutNode): if self.__is_lmapping_match(route_obj, lobj): route_obj.l_obj = lobj objs.append(route_obj) break if all_objs is True: maxlimits = 0 else: maxlimits = selectors.maxlimits return utils.GetFilteredObjects(objs, maxlimits)
def UpdatePolicer(tc, workload): if not workload.IsNaples(): return 0 PolicerClient = EzAccessStore.GetConfigClient( agent_api.ObjectTypes.POLICER) if tc.iterators.policertype == 'pps': multiplier = tc.iterators.pktsize + 40 # pktsize is MSS else: multiplier = 1 duration = 10 # default iperf run duration policer = PolicerClient.GetMatchingPolicerObject(workload.node_name, \ tc.iterators.direction, tc.iterators.policertype) if policer: spec = PolicerUpdateSpec(policer) workload.vnic.Update(spec) rate = (( (policer.rate * duration) + policer.burst) * multiplier) / duration else: rate = 0 return rate
def __init__(self, lobj, robj, fwdmode, routetblobj=None, tunobj=None, policyobj=None): super().__init__() self.Node = EzAccessStore.GetDUTNode() self.Clone(EzAccessStore.templates.Get('FLOW')) self.FlowMapId = next(ResmgrClient[self.Node].FlowIdAllocator) self.GID('FlowMap%d' % self.FlowMapId) self.FwdMode = fwdmode self.__lobj = lobj self.__robj = robj self.__routeTblObj = routetblobj self.__tunobj = tunobj self.__policyobj = policyobj self.__dev = EzAccessStoreClient[self.Node].GetDevice() self.localmapping = lobj #self.Show() return
def TestCaseVerify(tc): print(tc.packets.__dir__()) k = tc.packets.GetAll() print(k) if tc.config.root.FwdMode == 'IGW_NAPT' and tc.packets.IsKeyIn('FROM_HOST_PKT'): pkt = tc.packets.Get('FROM_HOST_PKT') proto_name = utils.GetIPProtoName(pkt.headers.ipv4.fields.proto).lower() post_stats = nat_pb.NatPbStats() for pb in tc.pvtdata.nat_port_blocks: if proto_name == pb.ProtoName: stats = pb.GetStats() post_stats.Add(stats) if GlobalOptions.dryrun: return True if post_stats.InUseCount - tc.pvtdata.pre_stats[proto_name].InUseCount != 1: logger.info("NAT in use count did not go up as expected (%d:%d)", tc.pvtdata.pre_stats[proto_name].InUseCount, post_stats.InUseCount) # TODO in CRUD cases, flow already exists so new session is not allocated # ignore stats for now #return False if post_stats.SessionCount - tc.pvtdata.pre_stats[proto_name].SessionCount != 1: logger.info("NAT session count did not go up as expected (%d:%d)", tc.pvtdata.pre_stats[proto_name].SessionCount, post_stats.SessionCount) # TODO in CRUD cases, flow already exists so new session is not allocated # ignore stats for now #return False if 'WORKFLOW_START' in tc.module.name: topo.ChosenFlowObjs.select_objs = False topo.ChosenFlowObjs.use_selected_objs = True elif 'WORKFLOW_END' in tc.module.name: topo.ChosenFlowObjs.Reset() NodeClient.Read(EzAccessStore.GetDUTNode()) return True
def GetMatchingObjects(selectors): dutNode = EzAccessStore.GetDUTNode() upgradeobjs = [EzAccessStoreClient[dutNode].GetUpgrade()] return utils.GetFilteredObjects(upgradeobjs, selectors.maxlimits, False)
if commitStatus: self.GetObjectByKey(node).SetBatchCommitStatus(commitStatus) return def Start(self, node): if utils.IsBatchingDisabled(): return None batchObj = self.GetObjectByKey(node) batchObj.SetNextEpoch() logger.info(f"Starting a batch for config objects with epoch {batchObj.Epoch()}") status = api.client[node].Start(api.ObjectTypes.BATCH, batchObj.GetBatchSpec()) # update batch context self.__updateObject(node, status) return status def Commit(self, node): if utils.IsBatchingDisabled(): return None batchObj = self.GetObjectByKey(node) if self.__commit_for_flows: api.client[node].Start(api.ObjectTypes.BATCH, batchObj.GetInvalidBatchSpec()) self.__commit_for_flows = False logger.info(f"Committing the batch with cookie 0x{batchObj.GetBatchCookie():0x}") status = api.client[node].Commit(api.ObjectTypes.BATCH, batchObj.GetBatchContext()) # invalidate batch context self.__updateObject(node, None, status) return client = BatchObjectClient() EzAccessStore.SetBatchClient(client)
def GetMatchingConfigObjects(self, selectors): objs = [] fwdmode = None ipsecmode = None mapsel = copy.deepcopy(selectors) key = 'FwdMode' # Consider it only if TEST is for MAPPING if mapsel.flow.GetValueByKey('FlType') != 'MAPPING': return objs # Get the forwarding mode, fwdmode is not applicable for local & remote fwdmode = mapsel.flow.GetValueByKey(key) mapsel.flow.filters.remove((key, fwdmode)) ipsecmode = mapsel.flow.GetValueByKey('IpsecMode') if ipsecmode: mapsel.flow.filters.remove(('IpsecMode', ipsecmode)) # Get the local2local info. key = 'L2LType' l2l = mapsel.flow.GetValueByKey(key) if l2l != None: mapsel.flow.filters.remove((key, l2l)) # Src and Dst check is not applicable for remote rmapsel = copy.deepcopy(mapsel) key = 'SourceGuard' value = rmapsel.flow.GetValueByKey(key) if value != None: rmapsel.flow.filters.remove((key, value)) assert (fwdmode == 'L2' or fwdmode == 'L3' or fwdmode == 'IGW' or \ fwdmode == 'IGW_NAT' or fwdmode == 'VPC_PEER' or \ fwdmode == 'POLICY' or fwdmode == 'L2L' or \ fwdmode == 'IGW_NAPT' or fwdmode == 'IGW_NAPT_SERVICE') == True selected_objs = [] if topo.ChosenFlowObjs.use_selected_objs == True and len( topo.ChosenFlowObjs.objs) != 0: matching_flows = topo.ChosenFlowObjs.GetMatchingFlowObjects( selectors) selected_objs = utils.GetFilteredObjects( matching_flows, topo.ChosenFlowObjs.GetMaxLimits()) maxlimits = selectors.maxlimits - len(selected_objs) if maxlimits <= 0: return utils.GetFilteredObjects(selected_objs, selectors.maxlimits) else: maxlimits = selectors.maxlimits dutNode = EzAccessStore.GetDUTNode() if fwdmode == 'VPC_PEER': rmappings = rmapping.GetMatchingObjects(mapsel, dutNode) lmappings = lmapping.GetMatchingObjects(mapsel, dutNode) for routetblobj in routetable.GetAllMatchingObjects(mapsel): if routetblobj.IsNatEnabled(): # Skip IGWs with nat flag set to True continue lmappingobjs = filter( lambda x: self.__is_lmapping_match(routetblobj, x), lmappings) rmappingobjs = filter( lambda x: self.__is_rmapping_match(routetblobj, x), rmappings) for robj in rmappingobjs: for lobj in lmappingobjs: obj = FlowMapObject(lobj, robj, fwdmode, routetblobj, robj.TUNNEL) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) elif fwdmode == 'IGW': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): for routetblobj in routetable.GetAllMatchingObjects(mapsel): if not self.__is_lmapping_match(routetblobj, lobj): continue if routetblobj.IsNatEnabled(): # Skip IGWs with nat flag set to True continue obj = FlowMapObject(lobj, None, fwdmode, routetblobj, routetblobj.TUNNEL) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) elif fwdmode == 'IGW_NAT': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): if hasattr(lobj, "PublicIP") == False: continue for routetblobj in routetable.GetAllMatchingObjects(mapsel): if not self.__is_lmapping_match(routetblobj, lobj): continue if not routetblobj.IsNatEnabled(): # Skip IGWs without nat flag set to True continue obj = FlowMapObject(lobj, None, fwdmode, routetblobj, routetblobj.TUNNEL) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) elif fwdmode == 'IGW_NAPT': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): if hasattr(lobj, "PublicIP") == True: # skip VNICs which have floating IP continue for routetblobj in routetable.GetAllMatchingObjects(mapsel): if not self.__is_lmapping_match(routetblobj, lobj): continue if not routetblobj.IsNatEnabled(): # Skip IGWs without nat flag set to True continue obj = FlowMapObject(lobj, None, fwdmode, routetblobj, routetblobj.TUNNEL) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) elif fwdmode == 'IGW_NAPT_SERVICE': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): if hasattr(lobj, "PublicIP") == True: # skip VNICs which have floating IP continue for routetblobj in routetable.GetAllMatchingObjects(mapsel): if not self.__is_lmapping_match(routetblobj, lobj): continue obj = FlowMapObject(lobj, None, fwdmode, routetblobj, routetblobj.TUNNEL) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) elif fwdmode == 'POLICY': for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): for routetblobj in routetable.GetAllMatchingObjects(mapsel): if not self.__is_lmapping_match(routetblobj, lobj): continue obj = FlowMapObject(lobj, None, fwdmode, routetblobj, routetblobj.TUNNEL) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) elif fwdmode == "L2L": lobjs = lmapping.GetMatchingObjects(mapsel, dutNode) if l2l == 'VPC_PEER': for routetblobj in routetable.GetAllMatchingObjects(mapsel): smappingobjs = filter( lambda x: self.__is_lmapping_match(routetblobj, x), lobjs) dmappingobjs = filter( lambda x: self.__is_lmapping_extract( routetblobj.PeerVPCId, x), lobjs) for s in smappingobjs: for d in dmappingobjs: obj = FlowMapObject(s, d, fwdmode) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) objs = utils.GetFilteredObjects(objs, maxlimits) utils.MergeFilteredObjects(objs, selected_objs) return objs for s in lobjs: if not self.__is_lmapping_valid(s): continue for d in lobjs: if not self.__is_lmapping_valid(d): continue if s.MappingId == d.MappingId: continue if l2l == 'SAME_VNIC': # Select ips from same vnic. if s.VNIC.VnicId != d.VNIC.VnicId: continue elif l2l == 'SAME_SUBNET': # Select ips from same subnet but different vnic if s.VNIC.VnicId == d.VNIC.VnicId: continue if s.VNIC.SUBNET.SubnetId != d.VNIC.SUBNET.SubnetId: continue elif l2l == 'SAME_VPC': # Select ips from different subnet in a VPC if s.VNIC.SUBNET.SubnetId == d.VNIC.SUBNET.SubnetId: continue if s.VNIC.SUBNET.VPC.VPCId != d.VNIC.SUBNET.VPC.VPCId: continue obj = FlowMapObject(s, d, fwdmode) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) else: for lobj in lmapping.GetMatchingObjects(mapsel, dutNode): if not self.__is_lmapping_valid(lobj): continue for robj in rmapping.GetMatchingObjects(rmapsel, dutNode): if lobj.VNIC.SUBNET.VPC.VPCId != robj.SUBNET.VPC.VPCId: continue # Select mappings from the same subnet if L2 is set if fwdmode == 'L2': if lobj.VNIC.SUBNET.SubnetId != robj.SUBNET.SubnetId: continue else: if lobj.VNIC.SUBNET.SubnetId == robj.SUBNET.SubnetId: continue if ipsecmode: if 'TUNNEL' in ipsecmode and \ not robj.TUNNEL.IsIpsecTunnelMode(): continue elif 'TRANSPORT' in ipsecmode and \ not robj.TUNNEL.IsIpsecTransportMode(): continue obj = FlowMapObject(lobj, robj, fwdmode, tunobj=robj.TUNNEL) if IsAlreadySelected(obj, selected_objs): continue objs.append(obj) objs = utils.GetFilteredObjects(objs, maxlimits) utils.MergeFilteredObjects(objs, selected_objs) return objs