Bug 3244 - SFC Improvements for distributed classifier, robustness
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / SourceMapper.java
old mode 100644 (file)
new mode 100755 (executable)
index b0871c8..f67851c
@@ -14,10 +14,12 @@ import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtil
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction;
 
 import java.math.BigInteger;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
@@ -30,9 +32,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
 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.inventory.rev130819.NodeConnectorId;
@@ -42,6 +47,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,10 +62,11 @@ public class SourceMapper extends FlowTable {
     protected static final Logger LOG = LoggerFactory.getLogger(SourceMapper.class);
 
     // TODO Li alagalah Improve UT coverage for this class.
-    public static final short TABLE_ID = 1;
+    public static short TABLE_ID;
 
-    public SourceMapper(OfContext ctx) {
+    public SourceMapper(OfContext ctx, short tableId) {
         super(ctx);
+        TABLE_ID = tableId;
     }
 
     @Override
@@ -70,27 +77,30 @@ public class SourceMapper extends FlowTable {
     @Override
     public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
 
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
+        // Handle case where packets from from External
         for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
             OfOverlayContext ofc = ep.getAugmentation(OfOverlayContext.class);
-            if (ofc != null && ofc.getNodeConnectorId() != null
-                    && (ofc.getLocationType() == null || LocationType.Internal.equals(ofc.getLocationType()))
-                    && ep.getTenant() != null && (ep.getEndpointGroup() != null || ep.getEndpointGroups() != null)) {
 
-                IndexedTenant tenant = ctx.getPolicyResolver().getTenant(ep.getTenant());
-                if (tenant == null)
-                    continue;
+            IndexedTenant tenant = ctx.getPolicyResolver().getTenant(ep.getTenant());
+            if (tenant == null)
+                continue;
+
+            EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, ep);
 
-                EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, ep);
-                EgKey sepg = new EgKey(ep.getTenant(), ep.getEndpointGroup());
+            createRemoteTunnels(flowMap, nodeId, ep, policyInfo, epFwdCtxOrds);
 
-                createRemoteTunnels(flowMap, nodeId, ep, policyInfo, epFwdCtxOrds);
+            if (ep.getTenant() == null || (ep.getEndpointGroup() == null && ep.getEndpointGroups() == null)) {
+                continue;
+            }
 
+            if (ofc != null && ofc.getNodeConnectorId() != null
+                    && (ofc.getLocationType() == null || LocationType.Internal.equals(ofc.getLocationType()))) {
                 /**
                  * Sync the local EP information.
                  */
-                syncEP(flowMap, policyInfo, nodeId, ep, ofc, sepg, epFwdCtxOrds);
+                syncEP(flowMap, nodeId, ep, ofc.getNodeConnectorId(), epFwdCtxOrds);
             }
         }
     }
@@ -116,11 +126,9 @@ public class SourceMapper extends FlowTable {
             for (EgKey peer : peers) {
                 for (NodeId remoteNodeId : ctx.getEndpointManager().getNodesForGroup(peer)) {
 
-                    // Only put tunnels on destination nodes
-                    if (remoteNodeId.getValue().equals(nodeId.getValue())) {
-                        continue;
-                    }
-                    NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(remoteNodeId);
+                    // Please do not check for remote v local nodeID, we need local to local tunnels
+                    // in the case of chaining - The Great Dr Sunal.
+                    NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(remoteNodeId, TunnelTypeVxlan.class);
                     if (tunPort == null) {
                         LOG.trace("No tunnel port for tunnel in SourceMapper between local:{} and remote:{}",
                                 nodeId.getValue(), remoteNodeId.getValue());
@@ -137,12 +145,6 @@ public class SourceMapper extends FlowTable {
 
         int fdId = epFwdCtxOrds.getFdId();
 
-        FlowId flowid = new FlowId(new StringBuilder().append(tunPort.getValue())
-            .append("|tunnel|")
-            .append("|")
-            .append(fdId)
-            .toString());
-
         MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
         addNxTunIdMatch(mb, fdId);
 
@@ -159,10 +161,12 @@ public class SourceMapper extends FlowTable {
 
         Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
 
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "tunnelFdId", match);
         FlowBuilder flowb = base().setId(flowid)
             .setPriority(Integer.valueOf(150))
-            .setMatch(mb.build())
-            .setInstructions(instructions(applyActionIns(fdReg), gotoTableIns((short) (TABLE_ID + 1))));
+            .setMatch(match)
+            .setInstructions(instructions(applyActionIns(fdReg), gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
         return flowb.build();
     }
 
@@ -175,21 +179,9 @@ public class SourceMapper extends FlowTable {
         int l3Id = epFwdCtxOrds.getL3Id();
         int tunnelId = epFwdCtxOrds.getTunnelId();
 
-        FlowId flowid = new FlowId(new StringBuilder().append(tunPort.getValue())
-            .append("|tunnel|")
-            .append(egId)
-            .append("|")
-            .append(bdId)
-            .append("|")
-            .append(fdId)
-            .append("|")
-            .append(l3Id)
-            .append("|")
-            .append(tunnelId)
-            .toString());
-
         MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
         addNxTunIdMatch(mb, tunnelId);
+
         Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId));
         // set condition group register to all ones to
         // bypass
@@ -205,17 +197,18 @@ public class SourceMapper extends FlowTable {
         Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId));
         Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
         Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id));
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "tunnel", match);
         FlowBuilder flowb = base().setId(flowid)
             .setPriority(Integer.valueOf(150))
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(
                     instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),
-                            gotoTableIns((short) (TABLE_ID + 1))));
+                            gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
         return flowb.build();
     }
 
-    private void syncEP(FlowMap flowMap, PolicyInfo policyInfo, NodeId nodeId, Endpoint ep, OfOverlayContext ofc,
-            EgKey egKey, EndpointFwdCtxOrdinals epFwdCtxOrds) throws Exception {
+    private void syncEP(FlowMap flowMap, NodeId nodeId, Endpoint ep, NodeConnectorId ncId, EndpointFwdCtxOrdinals epFwdCtxOrds) throws Exception {
 
         // TODO alagalah Li/Be: We should also match on EndpointL3 with the appropriate
         // network containment. This would solve a lot of problems and prepare for EndpointL3 RPC.
@@ -225,35 +218,25 @@ public class SourceMapper extends FlowTable {
         int fdId = epFwdCtxOrds.getFdId();
         int l3Id = epFwdCtxOrds.getL3Id();
         int cgId = epFwdCtxOrds.getCgId();
+        int tunnelId = epFwdCtxOrds.getTunnelId();
 
-        FlowId flowid = new FlowId(new StringBuilder().append(ofc.getNodeConnectorId().getValue())
-            .append("|")
-            .append(ep.getMacAddress().getValue())
-            .append("|")
-            .append(egId)
-            .append("|")
-            .append(bdId)
-            .append("|")
-            .append(fdId)
-            .append("|")
-            .append(l3Id)
-            .append("|")
-            .append(cgId)
-            .toString());
         Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId));
         Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(cgId));
         Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId));
         Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
         Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id));
+        Action tunIdAction = nxLoadTunIdAction(BigInteger.valueOf(tunnelId), false);
+
+        Match match = new MatchBuilder().setEthernetMatch(ethernetMatch(ep.getMacAddress(), null, null))
+                .setInPort(ncId)
+                .build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "ep", match);
         FlowBuilder flowb = base().setPriority(Integer.valueOf(100))
             .setId(flowid)
-            .setMatch(
-                    new MatchBuilder().setEthernetMatch(ethernetMatch(ep.getMacAddress(), null, null))
-                        .setInPort(ofc.getNodeConnectorId())
-                        .build())
+            .setMatch(match)
             .setInstructions(
-                    instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),
-                            gotoTableIns((short) (TABLE_ID + 1))));
+                    instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg,tunIdAction),
+                            gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
         flowMap.writeFlow(nodeId, TABLE_ID, flowb.build());
     }