@Test public void syncExternalEndpointFlows_L3Flow() { DestinationMapperFlows flows = mock(DestinationMapperFlows.class); Collection<EndpointL3Prefix> endpointL3PrefixCollection = new HashSet<>(); List<EndpointL3Gateways> endpointL3GatewaysList = new ArrayList<>(); EndpointL3PrefixBuilder endpointL3PrefixBuilder = new EndpointL3PrefixBuilder(); EndpointL3GatewaysBuilder endpointL3GatewaysBuilder = new EndpointL3GatewaysBuilder(); endpointL3GatewaysList.add(endpointL3GatewaysBuilder.build()); endpointL3PrefixBuilder.setEndpointL3Gateways(endpointL3GatewaysList); endpointL3PrefixCollection.add(endpointL3PrefixBuilder.build()); Set<NodeConnectorId> externalPorts = new HashSet<>(); externalPorts.add(new NodeConnectorId(CONNECTOR_0)); externalPorts.add(new NodeConnectorId(CONNECTOR_1)); EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); endpointBuilder.setL3Address(getL3AddressList(IPV4_1, L3C_ID)); Endpoint endpoint = endpointBuilder.build(); EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_2, MAC_0, CONNECTOR_0); List<Subnet> subnets = new ArrayList<>(); SubnetBuilder subnetBuilder = new SubnetBuilder(); subnetBuilder.setId(new SubnetId(SUBNET_0)); subnetBuilder.setParent(new ContextId(L3C_ID)); subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_2))); subnets.add(subnetBuilder.build()); List<L3Context> l3Contexts = new ArrayList<>(); L3ContextBuilder l3ContextBuilder = new L3ContextBuilder(); l3ContextBuilder.setId(L3C_ID); l3Contexts.add(l3ContextBuilder.build()); List<ExternalImplicitGroup> externalImplicitGroups = new ArrayList<>(); ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder(); externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0); externalImplicitGroups.add(externalImplicitGroupBuilder.build()); ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder(); forwardingContextBuilder.setSubnet(subnets); forwardingContextBuilder.setL3Context(l3Contexts); TenantBuilder peerTenantBuilder = buildTenant(); peerTenantBuilder.setForwardingContext(buildTenant().getForwardingContext()); peerTenantBuilder.setPolicy(new PolicyBuilder() .setSubjectFeatureInstances(getSubjectFeatureInstances()) .setEndpointGroup(getEndpointGroups()) .setExternalImplicitGroup(externalImplicitGroups) .build()); Tenant peerTenant = peerTenantBuilder.build(); Endpoint peerEndpoint = peerEndpointBuilder.build(); Collection<Endpoint> peerEndpoints = new ArrayList<>(); peerEndpoints.add(peerEndpoint); when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(peerTenant)); 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(endpointManager.getEndpointsL3PrefixForTenant(any(TenantId.class))).thenReturn(endpointL3PrefixCollection); when(endpointManager.getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), any(TenantId.class))) .thenReturn(buildL3Endpoint(IPV4_1, IPV4_2, MAC_0, L2BD_ID.getValue()).build()); when(endpointManager.getEndpoint(any(EpKey.class))).thenReturn(endpoint); when(switchManager.getExternalPorts(any(NodeId.class))).thenReturn(externalPorts); destinationMapper.syncEndpointFlows(flows, NODE_ID, endpoint, ofWriter); verify(ctx, times(16)).getTenant(any(TenantId.class)); verify(ctx, times(9)).getEndpointManager(); verify(ctx, times(1)).getPolicyManager(); verify(ctx, times(4)).getCurrentPolicy(); verify(flows, times(1)).createExternalL3RoutedFlow(anyShort(), anyInt(), any(Endpoint.class), any(Endpoint.class), any(L3Address.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; }