@Test public void syncExternalEndpointFlows_L2Flow() { DestinationMapperFlows flows = mock(DestinationMapperFlows.class); Set<NodeConnectorId> externalPorts = new HashSet<>(); externalPorts.add(CONNECTOR_0); externalPorts.add(CONNECTOR_1); EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_2, MAC_0, CONNECTOR_0); peerEndpointBuilder.setNetworkContainment(new SubnetId(SUBNET_1)); List<ExternalImplicitGroup> externalImplicitGroups = new ArrayList<>(); ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder(); externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0); externalImplicitGroups.add(externalImplicitGroupBuilder.build()); TenantBuilder peerTenantBuilder = buildTenant(); peerTenantBuilder.setPolicy(new PolicyBuilder() .setEndpointGroup(getEndpointGroups()) .setSubjectFeatureInstances(getSubjectFeatureInstances()) .setExternalImplicitGroup(externalImplicitGroups) .build()); Endpoint peerEndpoint = peerEndpointBuilder.build(); Collection<Endpoint> peerEndpoints = new ArrayList<>(); peerEndpoints.add(peerEndpoint); when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(peerTenantBuilder.build())); when(ctx.getEndpointManager()).thenReturn(endpointManager); when(ctx.getPolicyManager()).thenReturn(policyManager); when(ctx.getSwitchManager()).thenReturn(switchManager); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); when(endpointManager.getEndpointsForGroup(any(EgKey.class))).thenReturn(peerEndpoints); when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(peerEndpoints); when(switchManager.getExternalPorts(any(NodeId.class))).thenReturn(externalPorts); destinationMapper.syncEndpointFlows(flows, NODE_ID, endpointBuilder.build(), ofWriter); verify(ctx, times(14)).getTenant(any(TenantId.class)); verify(ctx, times(7)).getEndpointManager(); verify(ctx, times(1)).getPolicyManager(); verify(ctx, times(4)).getCurrentPolicy(); verify(flows, times(1)).createExternalL2Flow(anyShort(), anyInt(), any(Endpoint.class), anySetOf(NodeConnectorId.class), eq(ofWriter)); }
@VisibleForTesting void syncEndpointFlows(DestinationMapperFlows flows, NodeId nodeId, Endpoint endpoint, OfWriter ofWriter) { SetMultimap<EpKey, EpKey> visited = HashMultimap.create(); Set<EndpointGroupId> groupIds = utils.getAllEndpointGroups(endpoint); for (EndpointGroupId groupId : groupIds) { EgKey groupKey = new EgKey(endpoint.getTenant(), groupId); Set<EgKey> peers = Sets.union(Collections.singleton(groupKey), ctx.getCurrentPolicy().getPeers(groupKey)); for (EgKey peer : peers) { Collection<Endpoint> endpointsForGroup = new HashSet<>(); endpointsForGroup.addAll(ctx.getEndpointManager().getEndpointsForGroup(peer)); endpointsForGroup.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)); for (Endpoint peerEndpoint : endpointsForGroup) { subnetsByTenant.put(peerEndpoint.getTenant(), utils.getSubnets(endpoint.getTenant())); EpKey epKey = new EpKey(endpoint.getL2Context(), endpoint.getMacAddress()); EpKey peerEpKey = new EpKey(peerEndpoint.getL2Context(), peerEndpoint.getMacAddress()); if (visited.get(epKey) != null && visited.get(epKey).contains(peerEpKey)) { continue; } IndexedTenant endpointTenant = utils.getIndexedTenant(endpoint.getTenant()); IndexedTenant peerTenant = utils.getIndexedTenant(peerEndpoint.getTenant()); if (endpointTenant == null || peerTenant == null) { LOG.debug("Source or destination endpoint references empty tenant. SrcEp: {} DestEp: {}", endpointTenant, peerTenant); continue; } EndpointFwdCtxOrdinals endpointOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); EndpointFwdCtxOrdinals peerOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEndpoint); if (endpointOrdinals == null || peerOrdinals == null) { LOG.debug("Source od destination endpoint ordinals are null. SrcOrdinals: {} DestOrdinals: {}", endpointOrdinals, peerOrdinals); continue; } if (peerEndpoint.getEndpointGroup() == null && peerEndpoint.getEndpointGroups() == null) { LOG.debug("Didn't process endpoint {} due to EPG(s) being null", peerEndpoint.getKey()); continue; } List<Subnet> localSubnets = utils.getLocalSubnets(nodeId); if (localSubnets == null) { LOG.error("No subnets could be found locally for node: {}", nodeId); continue; } OfOverlayContext peerContext = peerEndpoint.getAugmentation(OfOverlayContext.class); Subnet epSubnet = endpointTenant.resolveSubnet(new SubnetId(endpoint.getNetworkContainment())); Endpoint l2GatewayEp = utils.getL2EpOfSubnetGateway(endpoint.getTenant(), epSubnet); boolean peerEpIsExternal = peerEndpoint.getNetworkContainment() != null && EndpointManager.isExternal(peerEndpoint, peerTenant.getExternalImplicitGroups()); boolean subnetGwIsExternal = l2GatewayEp != null && EndpointManager.isExternal(l2GatewayEp, utils.getIndexedTenant(endpoint.getTenant()).getExternalImplicitGroups()); if (peerEpIsExternal || subnetGwIsExternal) { Set<NodeConnectorId> externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); syncExternalFlows(flows, endpoint, peerEndpoint, l2GatewayEp, externalPorts, ofWriter); } else if (peerContext != null && !Objects.equals(peerContext.getNodeId(), nodeId)) { syncRemoteFlows(flows, endpoint, peerEndpoint, peerContext, nodeId, endpointOrdinals, peerOrdinals, localSubnets, ofWriter); } visited.put(epKey, peerEpKey); } } } }
DestinationMapper extends FlowTable { @VisibleForTesting void syncEndpointFlows(DestinationMapperFlows flows, NodeId nodeId, Endpoint endpoint, OfWriter ofWriter) { SetMultimap<EpKey, EpKey> visited = HashMultimap.create(); Set<EndpointGroupId> groupIds = utils.getAllEndpointGroups(endpoint); for (EndpointGroupId groupId : groupIds) { EgKey groupKey = new EgKey(endpoint.getTenant(), groupId); Set<EgKey> peers = Sets.union(Collections.singleton(groupKey), ctx.getCurrentPolicy().getPeers(groupKey)); for (EgKey peer : peers) { Collection<Endpoint> endpointsForGroup = new HashSet<>(); endpointsForGroup.addAll(ctx.getEndpointManager().getEndpointsForGroup(peer)); endpointsForGroup.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)); for (Endpoint peerEndpoint : endpointsForGroup) { subnetsByTenant.put(peerEndpoint.getTenant(), utils.getSubnets(endpoint.getTenant())); EpKey epKey = new EpKey(endpoint.getL2Context(), endpoint.getMacAddress()); EpKey peerEpKey = new EpKey(peerEndpoint.getL2Context(), peerEndpoint.getMacAddress()); if (visited.get(epKey) != null && visited.get(epKey).contains(peerEpKey)) { continue; } IndexedTenant endpointTenant = utils.getIndexedTenant(endpoint.getTenant()); IndexedTenant peerTenant = utils.getIndexedTenant(peerEndpoint.getTenant()); if (endpointTenant == null || peerTenant == null) { LOG.debug("Source or destination endpoint references empty tenant. SrcEp: {} DestEp: {}", endpointTenant, peerTenant); continue; } EndpointFwdCtxOrdinals endpointOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); EndpointFwdCtxOrdinals peerOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEndpoint); if (endpointOrdinals == null || peerOrdinals == null) { LOG.debug("Source od destination endpoint ordinals are null. SrcOrdinals: {} DestOrdinals: {}", endpointOrdinals, peerOrdinals); continue; } if (peerEndpoint.getEndpointGroup() == null && peerEndpoint.getEndpointGroups() == null) { LOG.debug("Didn't process endpoint {} due to EPG(s) being null", peerEndpoint.getKey()); continue; } List<Subnet> localSubnets = utils.getLocalSubnets(nodeId); if (localSubnets == null) { LOG.error("No subnets could be found locally for node: {}", nodeId); continue; } OfOverlayContext peerContext = peerEndpoint.getAugmentation(OfOverlayContext.class); Subnet epSubnet = endpointTenant.resolveSubnet(new SubnetId(endpoint.getNetworkContainment())); Endpoint l2GatewayEp = utils.getL2EpOfSubnetGateway(endpoint.getTenant(), epSubnet); boolean peerEpIsExternal = peerEndpoint.getNetworkContainment() != null && EndpointManager.isExternal(peerEndpoint, peerTenant.getExternalImplicitGroups()); boolean subnetGwIsExternal = l2GatewayEp != null && EndpointManager.isExternal(l2GatewayEp, utils.getIndexedTenant(endpoint.getTenant()).getExternalImplicitGroups()); if (peerEpIsExternal || subnetGwIsExternal) { Set<NodeConnectorId> externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); syncExternalFlows(flows, endpoint, peerEndpoint, l2GatewayEp, externalPorts, ofWriter); } else if (peerContext != null && !Objects.equals(peerContext.getNodeId(), nodeId)) { syncRemoteFlows(flows, endpoint, peerEndpoint, peerContext, nodeId, endpointOrdinals, peerOrdinals, localSubnets, ofWriter); } visited.put(epKey, peerEpKey); } } } } }
DestinationMapper extends FlowTable { @VisibleForTesting void syncEndpointFlows(DestinationMapperFlows flows, NodeId nodeId, Endpoint endpoint, OfWriter ofWriter) { SetMultimap<EpKey, EpKey> visited = HashMultimap.create(); Set<EndpointGroupId> groupIds = utils.getAllEndpointGroups(endpoint); for (EndpointGroupId groupId : groupIds) { EgKey groupKey = new EgKey(endpoint.getTenant(), groupId); Set<EgKey> peers = Sets.union(Collections.singleton(groupKey), ctx.getCurrentPolicy().getPeers(groupKey)); for (EgKey peer : peers) { Collection<Endpoint> endpointsForGroup = new HashSet<>(); endpointsForGroup.addAll(ctx.getEndpointManager().getEndpointsForGroup(peer)); endpointsForGroup.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)); for (Endpoint peerEndpoint : endpointsForGroup) { subnetsByTenant.put(peerEndpoint.getTenant(), utils.getSubnets(endpoint.getTenant())); EpKey epKey = new EpKey(endpoint.getL2Context(), endpoint.getMacAddress()); EpKey peerEpKey = new EpKey(peerEndpoint.getL2Context(), peerEndpoint.getMacAddress()); if (visited.get(epKey) != null && visited.get(epKey).contains(peerEpKey)) { continue; } IndexedTenant endpointTenant = utils.getIndexedTenant(endpoint.getTenant()); IndexedTenant peerTenant = utils.getIndexedTenant(peerEndpoint.getTenant()); if (endpointTenant == null || peerTenant == null) { LOG.debug("Source or destination endpoint references empty tenant. SrcEp: {} DestEp: {}", endpointTenant, peerTenant); continue; } EndpointFwdCtxOrdinals endpointOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); EndpointFwdCtxOrdinals peerOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEndpoint); if (endpointOrdinals == null || peerOrdinals == null) { LOG.debug("Source od destination endpoint ordinals are null. SrcOrdinals: {} DestOrdinals: {}", endpointOrdinals, peerOrdinals); continue; } if (peerEndpoint.getEndpointGroup() == null && peerEndpoint.getEndpointGroups() == null) { LOG.debug("Didn't process endpoint {} due to EPG(s) being null", peerEndpoint.getKey()); continue; } List<Subnet> localSubnets = utils.getLocalSubnets(nodeId); if (localSubnets == null) { LOG.error("No subnets could be found locally for node: {}", nodeId); continue; } OfOverlayContext peerContext = peerEndpoint.getAugmentation(OfOverlayContext.class); Subnet epSubnet = endpointTenant.resolveSubnet(new SubnetId(endpoint.getNetworkContainment())); Endpoint l2GatewayEp = utils.getL2EpOfSubnetGateway(endpoint.getTenant(), epSubnet); boolean peerEpIsExternal = peerEndpoint.getNetworkContainment() != null && EndpointManager.isExternal(peerEndpoint, peerTenant.getExternalImplicitGroups()); boolean subnetGwIsExternal = l2GatewayEp != null && EndpointManager.isExternal(l2GatewayEp, utils.getIndexedTenant(endpoint.getTenant()).getExternalImplicitGroups()); if (peerEpIsExternal || subnetGwIsExternal) { Set<NodeConnectorId> externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); syncExternalFlows(flows, endpoint, peerEndpoint, l2GatewayEp, externalPorts, ofWriter); } else if (peerContext != null && !Objects.equals(peerContext.getNodeId(), nodeId)) { syncRemoteFlows(flows, endpoint, peerEndpoint, peerContext, nodeId, endpointOrdinals, peerOrdinals, localSubnets, ofWriter); } visited.put(epKey, peerEpKey); } } } } DestinationMapper(OfContext ctx, short tableId); }
DestinationMapper extends FlowTable { @VisibleForTesting void syncEndpointFlows(DestinationMapperFlows flows, NodeId nodeId, Endpoint endpoint, OfWriter ofWriter) { SetMultimap<EpKey, EpKey> visited = HashMultimap.create(); Set<EndpointGroupId> groupIds = utils.getAllEndpointGroups(endpoint); for (EndpointGroupId groupId : groupIds) { EgKey groupKey = new EgKey(endpoint.getTenant(), groupId); Set<EgKey> peers = Sets.union(Collections.singleton(groupKey), ctx.getCurrentPolicy().getPeers(groupKey)); for (EgKey peer : peers) { Collection<Endpoint> endpointsForGroup = new HashSet<>(); endpointsForGroup.addAll(ctx.getEndpointManager().getEndpointsForGroup(peer)); endpointsForGroup.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)); for (Endpoint peerEndpoint : endpointsForGroup) { subnetsByTenant.put(peerEndpoint.getTenant(), utils.getSubnets(endpoint.getTenant())); EpKey epKey = new EpKey(endpoint.getL2Context(), endpoint.getMacAddress()); EpKey peerEpKey = new EpKey(peerEndpoint.getL2Context(), peerEndpoint.getMacAddress()); if (visited.get(epKey) != null && visited.get(epKey).contains(peerEpKey)) { continue; } IndexedTenant endpointTenant = utils.getIndexedTenant(endpoint.getTenant()); IndexedTenant peerTenant = utils.getIndexedTenant(peerEndpoint.getTenant()); if (endpointTenant == null || peerTenant == null) { LOG.debug("Source or destination endpoint references empty tenant. SrcEp: {} DestEp: {}", endpointTenant, peerTenant); continue; } EndpointFwdCtxOrdinals endpointOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); EndpointFwdCtxOrdinals peerOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEndpoint); if (endpointOrdinals == null || peerOrdinals == null) { LOG.debug("Source od destination endpoint ordinals are null. SrcOrdinals: {} DestOrdinals: {}", endpointOrdinals, peerOrdinals); continue; } if (peerEndpoint.getEndpointGroup() == null && peerEndpoint.getEndpointGroups() == null) { LOG.debug("Didn't process endpoint {} due to EPG(s) being null", peerEndpoint.getKey()); continue; } List<Subnet> localSubnets = utils.getLocalSubnets(nodeId); if (localSubnets == null) { LOG.error("No subnets could be found locally for node: {}", nodeId); continue; } OfOverlayContext peerContext = peerEndpoint.getAugmentation(OfOverlayContext.class); Subnet epSubnet = endpointTenant.resolveSubnet(new SubnetId(endpoint.getNetworkContainment())); Endpoint l2GatewayEp = utils.getL2EpOfSubnetGateway(endpoint.getTenant(), epSubnet); boolean peerEpIsExternal = peerEndpoint.getNetworkContainment() != null && EndpointManager.isExternal(peerEndpoint, peerTenant.getExternalImplicitGroups()); boolean subnetGwIsExternal = l2GatewayEp != null && EndpointManager.isExternal(l2GatewayEp, utils.getIndexedTenant(endpoint.getTenant()).getExternalImplicitGroups()); if (peerEpIsExternal || subnetGwIsExternal) { Set<NodeConnectorId> externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); syncExternalFlows(flows, endpoint, peerEndpoint, l2GatewayEp, externalPorts, ofWriter); } else if (peerContext != null && !Objects.equals(peerContext.getNodeId(), nodeId)) { syncRemoteFlows(flows, endpoint, peerEndpoint, peerContext, nodeId, endpointOrdinals, peerOrdinals, localSubnets, ofWriter); } visited.put(epKey, peerEpKey); } } } } DestinationMapper(OfContext ctx, short tableId); @Override short getTableId(); @Override void sync(Endpoint endpoint, OfWriter ofWriter); }
DestinationMapper extends FlowTable { @VisibleForTesting void syncEndpointFlows(DestinationMapperFlows flows, NodeId nodeId, Endpoint endpoint, OfWriter ofWriter) { SetMultimap<EpKey, EpKey> visited = HashMultimap.create(); Set<EndpointGroupId> groupIds = utils.getAllEndpointGroups(endpoint); for (EndpointGroupId groupId : groupIds) { EgKey groupKey = new EgKey(endpoint.getTenant(), groupId); Set<EgKey> peers = Sets.union(Collections.singleton(groupKey), ctx.getCurrentPolicy().getPeers(groupKey)); for (EgKey peer : peers) { Collection<Endpoint> endpointsForGroup = new HashSet<>(); endpointsForGroup.addAll(ctx.getEndpointManager().getEndpointsForGroup(peer)); endpointsForGroup.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)); for (Endpoint peerEndpoint : endpointsForGroup) { subnetsByTenant.put(peerEndpoint.getTenant(), utils.getSubnets(endpoint.getTenant())); EpKey epKey = new EpKey(endpoint.getL2Context(), endpoint.getMacAddress()); EpKey peerEpKey = new EpKey(peerEndpoint.getL2Context(), peerEndpoint.getMacAddress()); if (visited.get(epKey) != null && visited.get(epKey).contains(peerEpKey)) { continue; } IndexedTenant endpointTenant = utils.getIndexedTenant(endpoint.getTenant()); IndexedTenant peerTenant = utils.getIndexedTenant(peerEndpoint.getTenant()); if (endpointTenant == null || peerTenant == null) { LOG.debug("Source or destination endpoint references empty tenant. SrcEp: {} DestEp: {}", endpointTenant, peerTenant); continue; } EndpointFwdCtxOrdinals endpointOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); EndpointFwdCtxOrdinals peerOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEndpoint); if (endpointOrdinals == null || peerOrdinals == null) { LOG.debug("Source od destination endpoint ordinals are null. SrcOrdinals: {} DestOrdinals: {}", endpointOrdinals, peerOrdinals); continue; } if (peerEndpoint.getEndpointGroup() == null && peerEndpoint.getEndpointGroups() == null) { LOG.debug("Didn't process endpoint {} due to EPG(s) being null", peerEndpoint.getKey()); continue; } List<Subnet> localSubnets = utils.getLocalSubnets(nodeId); if (localSubnets == null) { LOG.error("No subnets could be found locally for node: {}", nodeId); continue; } OfOverlayContext peerContext = peerEndpoint.getAugmentation(OfOverlayContext.class); Subnet epSubnet = endpointTenant.resolveSubnet(new SubnetId(endpoint.getNetworkContainment())); Endpoint l2GatewayEp = utils.getL2EpOfSubnetGateway(endpoint.getTenant(), epSubnet); boolean peerEpIsExternal = peerEndpoint.getNetworkContainment() != null && EndpointManager.isExternal(peerEndpoint, peerTenant.getExternalImplicitGroups()); boolean subnetGwIsExternal = l2GatewayEp != null && EndpointManager.isExternal(l2GatewayEp, utils.getIndexedTenant(endpoint.getTenant()).getExternalImplicitGroups()); if (peerEpIsExternal || subnetGwIsExternal) { Set<NodeConnectorId> externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); syncExternalFlows(flows, endpoint, peerEndpoint, l2GatewayEp, externalPorts, ofWriter); } else if (peerContext != null && !Objects.equals(peerContext.getNodeId(), nodeId)) { syncRemoteFlows(flows, endpoint, peerEndpoint, peerContext, nodeId, endpointOrdinals, peerOrdinals, localSubnets, ofWriter); } visited.put(epKey, peerEpKey); } } } } DestinationMapper(OfContext ctx, short tableId); @Override short getTableId(); @Override void sync(Endpoint endpoint, OfWriter ofWriter); static final MacAddress ROUTER_MAC; }