X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=renderers%2Fofoverlay%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgroupbasedpolicy%2Frenderer%2Fofoverlay%2Fflow%2FDestinationMapper.java;h=7250e509dc74a6e7cd9488139523547e91eca7d2;hb=refs%2Fchanges%2F93%2F31593%2F8;hp=8bdc97691a0fe5e6d659331b0e141ac7b34ca205;hpb=8e06c107791d70e4bf0a7088249910a1fa9637c1;p=groupbasedpolicy.git diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapper.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapper.java index 8bdc97691..7250e509d 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapper.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapper.java @@ -8,28 +8,61 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow; -import com.google.common.base.Optional; -import com.google.common.base.Strings; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Sets; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv4; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv6; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.groupAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpOpAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpShaAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpSpaAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpShaToArpThaAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpSpaToArpTpaAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveEthSrcToEthDstAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlDstAction; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlSrcAction; +import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; + import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.groupbasedpolicy.endpoint.EpKey; +import org.opendaylight.groupbasedpolicy.dto.EgKey; +import org.opendaylight.groupbasedpolicy.dto.EpKey; +import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals; -import org.opendaylight.groupbasedpolicy.resolver.EgKey; -import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo; -import org.opendaylight.groupbasedpolicy.resolver.TenantUtils; import org.opendaylight.groupbasedpolicy.util.IidFactory; +import org.opendaylight.groupbasedpolicy.util.TenantUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; @@ -38,7 +71,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.M import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; @@ -49,14 +81,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match; @@ -74,44 +105,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv4; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv6; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.createNodePath; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.groupAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpOpAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpShaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpSpaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpShaToArpThaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpSpaToArpTpaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveEthSrcToEthDstAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlDstAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlSrcAction; -import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs; +import com.google.common.base.Optional; +import com.google.common.base.Strings; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; /** * Manage the table that maps the destination address to the next hop for the @@ -147,11 +145,11 @@ public class DestinationMapper extends FlowTable { } @Override - public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception { + public void sync(NodeId nodeId, OfWriter ofWriter) throws Exception { TenantId currentTenant = null; - flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID)); + ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID)); SetMultimap visitedEps = HashMultimap.create(); Set epOrdSet = new HashSet<>(); @@ -165,7 +163,7 @@ public class DestinationMapper extends FlowTable { for (EndpointGroupId epgId : srcEpgIds) { EgKey epg = new EgKey(srcEp.getTenant(), epgId); - Set peers = Sets.union(Collections.singleton(epg), policyInfo.getPeers(epg)); + Set peers = Sets.union(Collections.singleton(epg), ctx.getCurrentPolicy().getPeers(epg)); for (EgKey peer : peers) { for (Endpoint peerEp : ctx.getEndpointManager().getEndpointsForGroup(peer)) { currentTenant = peerEp.getTenant(); @@ -176,12 +174,17 @@ public class DestinationMapper extends FlowTable { if (visitedEps.get(srcEpKey) != null && visitedEps.get(srcEpKey).contains(peerEpKey)) { continue; } - syncEP(flowMap, nodeId, policyInfo, srcEp, peerEp); + syncEP(ofWriter, nodeId, srcEp, peerEp); visitedEps.put(srcEpKey, peerEpKey); // Process subnets and flood-domains for epPeer - EndpointFwdCtxOrdinals epOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, + EndpointFwdCtxOrdinals epOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEp); + if (epOrds == null) { + LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", peerEp); + continue; + } + epOrdSet.add(epOrds); } } @@ -199,7 +202,7 @@ public class DestinationMapper extends FlowTable { Flow arpFlow = createRouterArpFlow(currentTenant, nodeId, sn, OrdinalFactory.getContextOrdinal(currentTenant, l3c.getId())); if (arpFlow != null) { - flowMap.writeFlow(nodeId, TABLE_ID, arpFlow); + ofWriter.writeFlow(nodeId, TABLE_ID, arpFlow); } else { LOG.debug( "Gateway ARP flow is not created, because virtual router IP has not been set for subnet {} .", @@ -210,8 +213,8 @@ public class DestinationMapper extends FlowTable { // Write broadcast flows per flood domain. for (EndpointFwdCtxOrdinals epOrd : epOrdSet) { - if (groupExists(nodeId, epOrd.getFdId())) { - flowMap.writeFlow(nodeId, TABLE_ID, createBroadcastFlow(epOrd)); + if (ofWriter.groupExists(nodeId, Integer.valueOf(epOrd.getFdId()).longValue())) { + ofWriter.writeFlow(nodeId, TABLE_ID, createBroadcastFlow(epOrd)); } } @@ -220,20 +223,25 @@ public class DestinationMapper extends FlowTable { if (prefixEps != null) { LOG.trace("DestinationMapper - Processing L3PrefixEndpoints"); for (EndpointL3Prefix prefixEp : prefixEps) { - Flow prefixFlow = createL3PrefixFlow(prefixEp, policyInfo, nodeId); - if (prefixFlow != null) { - flowMap.writeFlow(nodeId, TABLE_ID, prefixFlow); - LOG.trace("Wrote L3Prefix flow"); + List localSubnets = getLocalSubnets(nodeId); + if (localSubnets == null) { + continue; + } + for (Subnet localSubnet: localSubnets) { + Flow prefixFlow = createL3PrefixFlow(prefixEp, nodeId, localSubnet); + if (prefixFlow != null) { + ofWriter.writeFlow(nodeId, TABLE_ID, prefixFlow); + LOG.trace("Wrote L3Prefix flow"); + } } } } - } // set up next-hop destinations for all the endpoints in the endpoint // group on the node - private Flow createL3PrefixFlow(EndpointL3Prefix prefixEp, PolicyInfo policyInfo, NodeId nodeId) throws Exception { + private Flow createL3PrefixFlow(EndpointL3Prefix prefixEp, NodeId nodeId, Subnet subnet) throws Exception { /* * Priority: 100+lengthprefix * Match: prefix, l3c, "mac address of router" ? @@ -256,6 +264,10 @@ public class DestinationMapper extends FlowTable { return null; } EndpointL3 l3Ep = optL3Ep.get(); + if (l3Ep.getL2Context() == null || l3Ep.getMacAddress() == null) { + LOG.debug("L3 endpoint representing L3 gateway does not contain L2-context or MAC address. {}", l3Ep); + return null; + } Optional optL2Ep = readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointIid(l3Ep.getL2Context(), l3Ep.getMacAddress()), rTx); if (!optL2Ep.isPresent()) { @@ -263,12 +275,23 @@ public class DestinationMapper extends FlowTable { return null; } Endpoint l2Ep = optL2Ep.get(); - EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, l2Ep); + EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, l2Ep); + if (epFwdCtxOrds == null) { + LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", l2Ep); + return null; + } NetworkDomainId epNetworkContainment = getEPNetworkContainment(l2Ep); MacAddress epDestMac = l2Ep.getMacAddress(); MacAddress destSubnetGatewayMac = l2Ep.getMacAddress(); + L3Context destL3c = getL3ContextForSubnet(prefixEp.getTenant(), subnet); + if (destL3c == null || destL3c.getId() == null) { + LOG.error("No L3 Context found associated with subnet {}", subnet.getId()); + return null; + } + + MacAddress matcherMac = routerPortMac(destL3c, subnet.getVirtualRouterIp()); ArrayList l3instructions = new ArrayList<>(); List applyActions = new ArrayList<>(); @@ -282,21 +305,9 @@ public class DestinationMapper extends FlowTable { String nextHop=null; OfOverlayContext ofc = l2Ep.getAugmentation(OfOverlayContext.class); - LocationType location; - - if (ofc != null && ofc.getLocationType() != null) { - location = ofc.getLocationType(); - } else if (ofc != null) { - // Augmentation, but using default location - location = LocationType.Internal; - } else { - LOG.info("createL3PrefixFlow - Endpoint {} had no augmentation.", l2Ep); - return null; - } long portNum = -1; - - if (location.equals(LocationType.Internal)) { + if (EndpointManager.isInternal(l2Ep, ctx.getTenant(l2Ep.getTenant()).getExternalImplicitGroups())) { checkNotNull(ofc.getNodeConnectorId()); nextHop = ofc.getNodeConnectorId().getValue(); try { @@ -378,7 +389,7 @@ public class DestinationMapper extends FlowTable { return null; } - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, etherType)); + MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)); addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(epFwdCtxOrds.getL3Id()))); Match match = mb.build(); FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "L3prefix", match); @@ -391,11 +402,10 @@ public class DestinationMapper extends FlowTable { private Flow createBroadcastFlow(EndpointFwdCtxOrdinals epOrd) { MatchBuilder mb = new MatchBuilder() - .setEthernetMatch(new EthernetMatchBuilder() - .setEthernetDestination(new EthernetDestinationBuilder(). - setAddress(MULTICAST_MAC) - .setMask(MULTICAST_MAC).build()) - .build()); + .setEthernetMatch(new EthernetMatchBuilder().setEthernetDestination( + new EthernetDestinationBuilder().setAddress(MULTICAST_MAC) + .setMask(MULTICAST_MAC) + .build()).build()); addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(epOrd.getFdId()))); Match match = mb.build(); @@ -410,32 +420,6 @@ public class DestinationMapper extends FlowTable { return flowb.build(); } - private boolean groupExists(NodeId nodeId, Integer fdId) throws Exception { - // Fetch existing GroupTables - if (ctx.getDataBroker() == null) { - return false; - } - - ReadOnlyTransaction t = ctx.getDataBroker().newReadOnlyTransaction(); - InstanceIdentifier niid = createNodePath(nodeId); - Optional r = t.read(LogicalDatastoreType.CONFIGURATION, niid).get(); - if (!r.isPresent()) - return false; - FlowCapableNode fcn = r.get().getAugmentation(FlowCapableNode.class); - if (fcn == null) - return false; - - if (fcn.getGroup() != null) { - for (Group g : fcn.getGroup()) { - if (g.getGroupId().getValue().equals(Long.valueOf(fdId))) { // Group - // Exists. - return true; - } - } - } - return false; - } - private MacAddress routerPortMac(L3Context l3c, IpAddress ipAddress) { if (ctx.getDataBroker() == null) { @@ -468,7 +452,12 @@ public class DestinationMapper extends FlowTable { } private L3Context getL3ContextForSubnet(TenantId tenantId, Subnet sn) { - L3Context l3c = ctx.getPolicyResolver().getTenant(tenantId).resolveL3Context(sn.getId()); + IndexedTenant indexedTenant = ctx.getTenant(tenantId); + if (indexedTenant == null) { + LOG.debug("Tenant {} is null, cannot get L3 context", tenantId); + return null; + } + L3Context l3c = indexedTenant.resolveL3Context(sn.getId()); return l3c; } @@ -576,21 +565,39 @@ public class DestinationMapper extends FlowTable { return flowb.build(); } - private void syncEP(FlowMap flowMap, NodeId nodeId, PolicyInfo policyInfo, Endpoint srcEp, Endpoint destEp) + private void syncEP(OfWriter ofWriter, NodeId nodeId, Endpoint srcEp, Endpoint destEp) throws Exception { + if (ctx.getTenant(srcEp.getTenant()) == null + || ctx.getTenant(destEp.getTenant()) == null) { + LOG.debug("Source or destination EP references empty tenant srcEp:{} destEp:{}", srcEp, destEp); + return; + } + // TODO: Conditions messed up, but for now, send policyInfo until this // is fixed. - EndpointFwdCtxOrdinals destEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, destEp); - EndpointFwdCtxOrdinals srcEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, srcEp); + EndpointFwdCtxOrdinals destEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, destEp); + if (destEpFwdCtxOrds == null) { + LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", destEp); + return; + } + EndpointFwdCtxOrdinals srcEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, srcEp); + if (srcEpFwdCtxOrds == null) { + LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", srcEp); + return; + } + if (destEp.getTenant() == null || (destEp.getEndpointGroup() == null && destEp.getEndpointGroups() == null)) { - LOG.trace("Didn't process endpoint due to either tenant, or EPG(s) being null", destEp.getKey()); + if (destEp.getTenant() == null) { + LOG.debug("Didn't process endpoint {} due to tenant being null", destEp.getKey()); + } else { + LOG.debug("Didn't process endpoint {} due to EPG(s) being null", destEp.getKey()); + } return; } - OfOverlayContext ofc = destEp.getAugmentation(OfOverlayContext.class); - if (LocationType.External.equals(ofc.getLocationType())) { + if (EndpointManager.isExternal(destEp, ctx.getTenant(destEp.getTenant()).getExternalImplicitGroups())) { LOG.error("syncEp(): External endpoints should not be seen here."); return; } @@ -607,12 +614,13 @@ public class DestinationMapper extends FlowTable { return; } + OfOverlayContext ofc = destEp.getAugmentation(OfOverlayContext.class); if (Objects.equals(ofc.getNodeId(), nodeId)) { // this is a local endpoint; send to the approppriate local // port if (srcEpFwdCtxOrds.getBdId() == destEpFwdCtxOrds.getBdId()) { - flowMap.writeFlow(nodeId, TABLE_ID, createLocalL2Flow(destEp, destEpFwdCtxOrds, ofc)); + ofWriter.writeFlow(nodeId, TABLE_ID, createLocalL2Flow(destEp, destEpFwdCtxOrds, ofc)); } // TODO Li alagalah: Need to move to EndpointL3 for L3 processing. // The Endpoint conflation must end! @@ -630,7 +638,7 @@ public class DestinationMapper extends FlowTable { for (Subnet localSubnet : localSubnets) { Flow flow = createLocalL3RoutedFlow(destEp, l3a, destEpFwdCtxOrds, ofc, localSubnet); if (flow != null) { - flowMap.writeFlow(nodeId, TABLE_ID, flow); + ofWriter.writeFlow(nodeId, TABLE_ID, flow); } else { LOG.trace("Did not write remote L3 flow for endpoint {} and subnet {}", l3a.getIpAddress(), localSubnet.getIpPrefix().getValue()); @@ -644,7 +652,7 @@ public class DestinationMapper extends FlowTable { if (srcEpFwdCtxOrds.getBdId() == destEpFwdCtxOrds.getBdId()) { Flow remoteL2Flow = createRemoteL2Flow(destEp, nodeId, srcEpFwdCtxOrds, destEpFwdCtxOrds, ofc); if (remoteL2Flow != null) { - flowMap.writeFlow(nodeId, TABLE_ID, remoteL2Flow); + ofWriter.writeFlow(nodeId, TABLE_ID, remoteL2Flow); } } else { LOG.trace("DestinationMapper: RemoteL2Flow: not created, in different BDs src: {} dst: {}", @@ -667,7 +675,7 @@ public class DestinationMapper extends FlowTable { Flow remoteL3Flow = createRemoteL3RoutedFlow(destEp, l3a, nodeId, srcEpFwdCtxOrds, destEpFwdCtxOrds, ofc, localSubnet); if (remoteL3Flow != null) { - flowMap.writeFlow(nodeId, TABLE_ID, remoteL3Flow); + ofWriter.writeFlow(nodeId, TABLE_ID, remoteL3Flow); } else { LOG.trace("Did not write remote L3 flow for endpoint {} and subnet {}", l3a.getIpAddress(), localSubnet.getIpPrefix().getValue()); @@ -970,7 +978,10 @@ public class DestinationMapper extends FlowTable { MacAddress matcherMac = routerPortMac(destL3c, srcSubnet.getVirtualRouterIp()); MacAddress epDestMac = destEp.getMacAddress(); MacAddress destSubnetGatewayMac = routerPortMac(destL3c, destSubnet.getVirtualRouterIp()); - + if (srcSubnet.getId().getValue().equals(destSubnet.getId().getValue())) { + // This is our final destination, so match on actual EP mac. + matcherMac = epDestMac; + } ArrayList l3instructions = new ArrayList<>(); List applyActions = new ArrayList<>(); List l3ApplyActions = new ArrayList<>(); @@ -1027,8 +1038,11 @@ public class DestinationMapper extends FlowTable { applyActions.add(setdCG); applyActions.add(setNextHop); - Action setDlSrc = setDlSrcAction(destSubnetGatewayMac); - l3ApplyActions.add(setDlSrc); + // Lets not re-write the srcMac if its local. + if (!(matcherMac.getValue().equals(epDestMac.getValue()))) { + Action setDlSrc = setDlSrcAction(destSubnetGatewayMac); + l3ApplyActions.add(setDlSrc); + } Action setDlDst = setDlDstAction(epDestMac); l3ApplyActions.add(setDlDst); @@ -1083,8 +1097,7 @@ public class DestinationMapper extends FlowTable { * which we can't do because of the backwards way endpoints were * "architected". */ - return ctx.getPolicyResolver() - .getTenant(endpoint.getTenant()) + return ctx.getTenant(endpoint.getTenant()) .getEndpointGroup(endpoint.getEndpointGroup()) .getNetworkDomain(); } @@ -1092,10 +1105,6 @@ public class DestinationMapper extends FlowTable { private HashSet getSubnets(final TenantId tenantId) { - // if (subnetsByTenant.get(tenantId) != null) { - // return subnetsByTenant.get(tenantId); - // } - if (ctx.getDataBroker() == null) { return null; } @@ -1108,18 +1117,20 @@ public class DestinationMapper extends FlowTable { } catch (Exception e) { LOG.error("Could not read Tenant {}", tenantId, e); return null; + } finally { + t.close(); } - HashSet subnets = new HashSet(); - if (!tenantInfo.isPresent()) { LOG.warn("Tenant {} not found", tenantId); return null; } - subnets.addAll(tenantInfo.get().getSubnet()); - // subnetsByTenant.put(tenantId, subnets); - return subnets; + ForwardingContext fwCtx = tenantInfo.get().getForwardingContext(); + if (fwCtx == null || fwCtx.getSubnet() == null) { + return new HashSet<>(); + } + return new HashSet<>(fwCtx.getSubnet()); } // Need a method to get subnets for EPs attached to the node locally @@ -1132,8 +1143,8 @@ public class DestinationMapper extends FlowTable { for (Endpoint endpoint : endpointsForNode) { HashSet subnets = getSubnets(endpoint.getTenant()); if (subnets == null) { - LOG.error("No local subnets."); - return null; + LOG.debug("No local subnets in tenant {} for EP {}.", endpoint.getTenant(), endpoint.getKey()); + continue; } NetworkDomainId epNetworkContainment = getEPNetworkContainment(endpoint); for (Subnet subnet : subnets) {