Bug 3540: Implementation of FlowIds based on match data 58/20658/12
authorKonstantin Blagov <kblagov@cisco.com>
Mon, 18 May 2015 15:35:06 +0000 (17:35 +0200)
committerMartin Sunal <msunal@cisco.com>
Sat, 6 Jun 2015 09:33:22 +0000 (09:33 +0000)
Change-Id: Id5766bfbe3c065d5d4816402be73d79cee8f3871
Signed-off-by: Konstantin Blagov <kblagov@cisco.com>
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapper.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/EgressNatMapper.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/ExternalMapper.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowIdUtils.java [new file with mode: 0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTable.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/IngressNatMapper.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PortSecurity.java [changed mode: 0644->0755]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/SourceMapper.java [changed mode: 0644->0755]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcerTest.java

old mode 100644 (file)
new mode 100755 (executable)
index 02aa6d3..25c3985
@@ -8,45 +8,11 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
 
-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 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 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 org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.groupbasedpolicy.endpoint.EpKey;
@@ -68,6 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 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.InstructionsBuilder;
+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.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
@@ -107,11 +74,44 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-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 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;
 
 /**
  * Manage the table that maps the destination address to the next hop for the
@@ -151,7 +151,7 @@ public class DestinationMapper extends FlowTable {
 
         TenantId currentTenant = null;
 
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         SetMultimap<EpKey, EpKey> visitedEps = HashMultimap.create();
         Set<EndpointFwdCtxOrdinals> epOrdSet = new HashSet<>();
@@ -378,6 +378,8 @@ public class DestinationMapper extends FlowTable {
             return null;
         }
 
+        /*
+        // commented out because of the new FlowId implementation
         FlowId flowid = new FlowId(new StringBuilder().append(Integer.toString(epFwdCtxOrds.getL3Id()))
             .append("|l3prefix|")
             .append(ikey)
@@ -386,25 +388,33 @@ public class DestinationMapper extends FlowTable {
             .append("|")
             .append(nextHop)
             .toString());
+        */
         MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, etherType));
 //        MatchBuilder mb = new MatchBuilder();//.setLayer3Match(m);
         addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(epFwdCtxOrds.getL3Id())));
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "L3prefix", match);
         FlowBuilder flowb = base().setId(flowid)
             .setPriority(Integer.valueOf(BASE_L3_PRIORITY+prefixLength))
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build());
         return flowb.build();
     }
 
     private Flow createBroadcastFlow(EndpointFwdCtxOrdinals epOrd) {
-        FlowId flowId = new FlowId("broadcast|" + epOrd.getFdId());
-        MatchBuilder mb = new MatchBuilder().setEthernetMatch(new EthernetMatchBuilder().setEthernetDestination(
-                new EthernetDestinationBuilder().setAddress(MULTICAST_MAC).setMask(MULTICAST_MAC).build()).build());
+        MatchBuilder mb = new MatchBuilder()
+                            .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();
+        FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "broadcast", match);
         FlowBuilder flowb = base().setPriority(Integer.valueOf(140))
             .setId(flowId)
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(
                     instructions(applyActionIns(nxLoadTunIdAction(BigInteger.valueOf(epOrd.getFdId()), false),
                             groupAction(Long.valueOf(epOrd.getFdId())))));
@@ -499,22 +509,17 @@ public class DestinationMapper extends FlowTable {
 
             BigInteger intRouterMac = new BigInteger(1, bytesFromHexString(routerMac.getValue()));
 
-            FlowId flowId = new FlowId(new StringBuffer().append("routerarp|")
-                .append(sn.getId().getValue())
-                .append("|")
-                .append(ikey)
-                .append("|")
-                .append(l3Id)
-                .toString());
             MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP)).setLayer3Match(
                     new ArpMatchBuilder().setArpOp(Integer.valueOf(1))
                         .setArpTargetTransportAddress(new Ipv4Prefix(ikey + "/32"))
                         .build());
             addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(l3Id)));
 
+            Match match = mb.build();
+            FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "routerarp", match);
             FlowBuilder flowb = base().setPriority(150)
                 .setId(flowId)
-                .setMatch(mb.build())
+                .setMatch(match)
                 .setInstructions(
                         instructions(applyActionIns(nxMoveEthSrcToEthDstAction(), setDlSrcAction(routerMac),
                                 nxLoadArpOpAction(BigInteger.valueOf(2L)), nxMoveArpShaToArpThaAction(),
@@ -572,17 +577,13 @@ public class DestinationMapper extends FlowTable {
             .build();
         instructions.add(gotoTable);
 
-        FlowId flowid = new FlowId(new StringBuilder().append(epFwdCtxOrds.getBdId())
-            .append("|l2|")
-            .append(ep.getMacAddress().getValue())
-            .append("|")
-            .append(nextHop)
-            .toString());
         MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, ep.getMacAddress(), null));
         addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(epFwdCtxOrds.getBdId())));
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "localL2", match);
         FlowBuilder flowb = base().setId(flowid)
             .setPriority(Integer.valueOf(50))
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(new InstructionsBuilder().setInstruction(instructions).build());
         return flowb.build();
     }
@@ -831,26 +832,14 @@ public class DestinationMapper extends FlowTable {
             return null;
         }
 
-        FlowId flowid = new FlowId(new StringBuilder().append(Integer.toString(epFwdCtxOrds.getL3Id()))
-            .append("|l3|")
-            .append(ikey)
-            .append("|")
-            .append(Integer.toString(epFwdCtxOrds.getEpgId()))
-            .append("|")
-            .append(Integer.toString(epFwdCtxOrds.getCgId()))
-            .append("|")
-            .append(matcherMac)
-            .append("|")
-            .append(destSubnetGatewayMac)
-            .append("|")
-            .append(nextHop)
-            .toString());
         MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType))
             .setLayer3Match(m);
         addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(epFwdCtxOrds.getL3Id())));
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "localL3", match);
         FlowBuilder flowb = base().setId(flowid)
             .setPriority(Integer.valueOf(132))
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build());
         return flowb.build();
     }
@@ -931,19 +920,13 @@ public class DestinationMapper extends FlowTable {
             .build();
         instructions.add(gotoTable);
 
-        FlowId flowid = new FlowId(new StringBuilder().append(destEpFwdCtxOrds.getBdId())
-            .append("|l2|")
-            .append(ep.getMacAddress().getValue())
-            .append("|")
-            .append(srcEpFwdCtxOrds.getBdId())
-            .append("|")
-            .append(nextHop)
-            .toString());
         MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, ep.getMacAddress(), null));
         addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(destEpFwdCtxOrds.getBdId())));
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "remoteL2", match);
         FlowBuilder flowb = base().setId(flowid)
             .setPriority(Integer.valueOf(50))
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(new InstructionsBuilder().setInstruction(instructions).build());
 
         return flowb.build();
@@ -1098,25 +1081,14 @@ public class DestinationMapper extends FlowTable {
             return null;
         }
 
-        FlowId flowid = new FlowId(new StringBuilder().append(Integer.toString(destEpFwdCtxOrds.getL3Id()))
-            .append("|l3|")
-            .append(ikey)
-            .append("|")
-            .append(matcherMac)
-            .append("|")
-            .append(destSubnetGatewayMac)
-            .append("|")
-            .append(srcEpFwdCtxOrds.getL3Id())
-            .append("|")
-            .append(nextHop)
-            .toString());
         MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType))
             .setLayer3Match(m);
         addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(destEpFwdCtxOrds.getL3Id())));
-
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "remoteL3", match);
         FlowBuilder flowb = base().setId(flowid)
             .setPriority(Integer.valueOf(132))
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build());
         return flowb.build();
     }
old mode 100644 (file)
new mode 100755 (executable)
index fc87a7b..d62512d
@@ -56,7 +56,7 @@ public class EgressNatMapper extends FlowTable {
 
     public EgressNatMapper(OfContext ctx, short tableId) {
         super(ctx);
-        this.TABLE_ID=tableId;
+        TABLE_ID=tableId;
     }
 
     @Override
@@ -66,7 +66,7 @@ public class EgressNatMapper 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));
 
         Collection<EndpointL3> l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat();
         for (EndpointL3 l3Ep : l3Endpoints) {
old mode 100644 (file)
new mode 100755 (executable)
index 9e9490c..a37a3b6
@@ -24,6 +24,7 @@ import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 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.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.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
@@ -42,7 +43,7 @@ public class ExternalMapper extends FlowTable {
 
     public ExternalMapper(OfContext ctx, short tableId) {
         super(ctx);
-        this.TABLE_ID=tableId;
+        TABLE_ID = tableId;
     }
 
     @Override
@@ -58,12 +59,12 @@ public class ExternalMapper extends FlowTable {
             return;
         }
         // Default drop all
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         // Drop IP traffic that doesn't match a source IP rule
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(2), FlowUtils.ARP));
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(2), FlowUtils.IPv4));
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(2), FlowUtils.IPv6));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(2), FlowUtils.ARP, TABLE_ID));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(2), FlowUtils.IPv4, TABLE_ID));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(2), FlowUtils.IPv6, TABLE_ID));
         l3flow(flowMap,nodeId, 100, true);
         l3flow(flowMap,nodeId, 200, false);
     }
@@ -84,16 +85,13 @@ public class ExternalMapper extends FlowTable {
             etherType = FlowUtils.IPv4;
         }
 
-        FlowId flowid = new FlowId(new StringBuilder().append("ExternalMapper")
-            .append("|")
-            .append(etherType)
-            .toString());
+        Match match = new MatchBuilder().setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType))
+                .setLayer3Match(m)
+                .build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "ExternalMapper", match);
         Flow flow = base().setPriority(priority)
             .setId(flowid)
-            .setMatch(
-                    new MatchBuilder().setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType))
-                        .setLayer3Match(m)
-                        .build())
+            .setMatch(match)
             .setInstructions(instructions(applyActionIns(actionBuilderList)))
             .build();
 
diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowIdUtils.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowIdUtils.java
new file mode 100755 (executable)
index 0000000..51d38f4
--- /dev/null
@@ -0,0 +1,194 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
+
+import java.util.Comparator;
+import java.util.TreeSet;
+
+public class FlowIdUtils {
+
+    private static final String TABLE_ID_PREFIX = "t";
+    private static final String FLOWID_SEPARATOR = "|";
+    private static final String MATCH_PREFIX = "match[";
+    private static final String MATCH_SUFFIX = "]";
+    private static final String MATCH_SEPARATOR = ", ";
+
+    // *** flow from FlowTable (abstract parent) ***
+
+    /**
+     * For flow without match specified (actually, only "drop all" flow)
+     *
+     * @param prefix String
+     * @return FlowId
+     */
+    public static FlowId newFlowId(String prefix) {
+
+        return new FlowId(prefix);
+    }
+
+    /**
+     * FlowId based on match (with prefix like "t2|localL3|")
+     *
+     * @param tableId Short
+     * @param prefix String
+     * @param match Match
+     * @return FlowId
+     */
+    public static FlowId newFlowId(Short tableId, String prefix, Match match) {
+
+        return new FlowId((tableId != null ? TABLE_ID_PREFIX + tableId + FLOWID_SEPARATOR : "")
+                + prefix + FLOWID_SEPARATOR
+                + formatMatch(match));
+    }
+
+    private static String formatMatch(Match match) {
+        StringBuilder builder = new StringBuilder(MATCH_PREFIX);
+        boolean first = true;
+        if (match.getEthernetMatch() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getEthernetMatch());
+        }
+        if (match.getIcmpv4Match() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getIcmpv4Match());
+        }
+        if (match.getIcmpv6Match() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getIcmpv6Match());
+        }
+        if (match.getInPhyPort() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append("inPhyPort=").append(match.getInPhyPort());
+        }
+        if (match.getInPort() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append("inPort=").append(match.getInPort());
+        }
+        if (match.getIpMatch() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getIpMatch());
+        }
+        if (match.getLayer3Match() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getLayer3Match());
+        }
+        if (match.getLayer4Match() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getLayer4Match());
+        }
+        if (match.getMetadata() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getMetadata());
+        }
+        if (match.getProtocolMatchFields() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getProtocolMatchFields());
+        }
+        if (match.getTcpFlagMatch() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getTcpFlagMatch());
+        }
+        if (match.getTunnel() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getTunnel());
+        }
+        if (match.getVlanMatch() != null) {
+            if (first) {
+                first = false;
+            } else {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append(match.getVlanMatch());
+        }
+
+        // only one augmentation is used in Match at the moment;
+        // if in the future there will be more of them, similar handling has to be implemented
+        GeneralAugMatchNodesNodeTableFlow generalAug = match.getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
+        if(generalAug != null && generalAug.getExtensionList() != null) {
+            TreeSet<String> extensionAugmentationStrings = new TreeSet<>(new Comparator<String>() {
+                @Override
+                public int compare(String a, String b) {
+                    return Strings.nullToEmpty(a).compareTo(Strings.nullToEmpty(b));
+                }
+            });
+            for (ExtensionList e : generalAug.getExtensionList()) {
+                Extension ext = e.getExtension();
+                // only one augmentation is used in Extension at the moment;
+                // if in the future there will be more of them, similar handling has to be implemented,
+                // probing augmentations one by one and adding their toString results to our TreeSet
+                // (and every List<> in them needs to be cast to Set<> to avoid non-equivalence
+                // due to different element order, and possible element duplication)
+                NxAugMatchNodesNodeTableFlow nxAug = ext.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
+                if (nxAug != null) {
+                    extensionAugmentationStrings.add(nxAug.toString());
+                }
+            }
+
+            if (!first) {
+                builder.append(MATCH_SEPARATOR);
+            }
+            builder.append("GeneralAugMatchNodesNodeTableFlow[<ExtensionList>=")
+                    .append(Joiner.on(", ").skipNulls().join(extensionAugmentationStrings))
+                    .append(']');
+        }
+        builder.append(MATCH_SUFFIX);
+
+        return builder.toString();
+    }
+
+}
old mode 100644 (file)
new mode 100755 (executable)
index c541725..522935e
@@ -14,6 +14,7 @@ import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
 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.inventory.rev130819.NodeId;
 import org.slf4j.Logger;
@@ -77,21 +78,22 @@ public abstract class FlowTable extends OfTable {
      * Write a drop flow for the given ethertype at the given priority.
      * If the ethertype is null, then drop all traffic
      */
-    public Flow dropFlow(Integer priority, Long etherType) {
-        FlowId flowid = new FlowId(new StringBuilder()
-                .append("drop|")
-                .append(etherType)
-                .toString());
-
+    public Flow dropFlow(Integer priority, Long etherType, Short tableId) {
+        FlowId flowid;
         FlowBuilder flowb = base()
-                .setId(flowid)
                 .setPriority(priority)
                 .setInstructions(FlowUtils.dropInstructions());
-        if (etherType != null)
-            flowb.setMatch(new MatchBuilder()
-                    .setEthernetMatch(FlowUtils.ethernetMatch(null, null,
-                            etherType))
-                    .build());
+        if (etherType != null) {
+            MatchBuilder mb = new MatchBuilder()
+                    .setEthernetMatch(
+                            FlowUtils.ethernetMatch(null, null, etherType));
+            Match match = mb.build();
+            flowid = FlowIdUtils.newFlowId(tableId, "drop", match);
+            flowb.setMatch(match);
+        } else {
+            flowid = FlowIdUtils.newFlowId("dropAll");
+        }
+        flowb.setId(flowid);
         return flowb.build();
     }
 
old mode 100644 (file)
new mode 100755 (executable)
index 152a86e..1189d2a
@@ -80,7 +80,7 @@ public class IngressNatMapper extends FlowTable {
 
     public IngressNatMapper(OfContext ctx, short tableId) {
         super(ctx);
-        this.TABLE_ID = tableId;
+        TABLE_ID = tableId;
     }
 
     @Override
@@ -91,7 +91,7 @@ public class IngressNatMapper 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));
 
         // TODO Bug 3546 - Difficult: External port is unrelated to Tenant, L3C, L2BD..
 
old mode 100644 (file)
new mode 100755 (executable)
index a121d2d..d03f943
@@ -120,7 +120,7 @@ public class PolicyEnforcer 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));
 
         NodeConnectorId tunPort = SwitchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class);
         if (tunPort != null) {
@@ -224,20 +224,16 @@ public class PolicyEnforcer extends FlowTable {
         Long etherType = FlowUtils.ARP;
         // L2 Classifier so 20,000 for now
         Integer priority = 20000;
-        FlowId flowid = new FlowId(new StringBuilder().append("arp")
-            .append("|")
-            .append(etherType)
-            .append("|")
-            .append(fdId)
-            .toString());
 
         MatchBuilder mb = new MatchBuilder().setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType));
 
         addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(fdId)));
 
+        Match match = mb.build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "arp", match);
         Flow flow = base().setPriority(priority)
             .setId(flowid)
-            .setMatch(mb.build())
+            .setMatch(match)
             .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))))
             .build();
         return flow;
@@ -245,12 +241,13 @@ public class PolicyEnforcer extends FlowTable {
 
     private Flow allowSameEpg(int sepgId, int depgId) {
 
-        FlowId flowId = new FlowId(new StringBuilder().append("intraallow|").append(sepgId).toString());
         MatchBuilder mb = new MatchBuilder();
         addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, Long.valueOf(sepgId)),
                 RegMatch.of(NxmNxReg2.class, Long.valueOf(depgId)));
+        Match match = mb.build();
+        FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "intraallow", match);
         FlowBuilder flow = base().setId(flowId)
-            .setMatch(mb.build())
+            .setMatch(match)
             .setPriority(65000)
             .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
         return flow.build();
@@ -258,11 +255,12 @@ public class PolicyEnforcer extends FlowTable {
 
     private Flow allowFromTunnel(NodeConnectorId tunPort) {
 
-        FlowId flowId = new FlowId("tunnelallow");
         MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
         addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
+        Match match = mb.build();
+        FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "tunnelallow", match);
         FlowBuilder flow = base().setId(flowId)
-            .setMatch(mb.build())
+            .setMatch(match)
             .setPriority(65000)
             .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
         return flow.build();
@@ -437,13 +435,11 @@ public class PolicyEnforcer extends FlowTable {
             flowMatchBuilders.addAll(matchBuildersToResolve);
         }
 
-
-
         FlowBuilder flow = base().setPriority(Integer.valueOf(priority));
-        for (MatchBuilder match : flowMatchBuilders) {
-            Match m = match.build();
-            FlowId flowId = new FlowId(baseId + "|" + m.toString());
-            flow.setMatch(m)
+        for (MatchBuilder mb : flowMatchBuilders) {
+            Match match = mb.build();
+            FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "cg", match);
+            flow.setMatch(match)
                 .setId(flowId)
                 .setPriority(Integer.valueOf(priority));
                         // If destination is External, the last Action ALLOW must be changed to goto NAT/External table.
old mode 100644 (file)
new mode 100755 (executable)
index 419591b..93a515d
@@ -19,6 +19,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 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.endpoint.rev140421.endpoint.fields.L3Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
@@ -72,12 +73,12 @@ public class PortSecurity extends FlowTable {
         }
 
         // Default drop all
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
 
         // Drop IP traffic that doesn't match a source IP rule
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(110), FlowUtils.ARP));
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(111), FlowUtils.IPv4));
-        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(112), FlowUtils.IPv6));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(110), FlowUtils.ARP, TABLE_ID));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(111), FlowUtils.IPv4, TABLE_ID));
+        flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(112), FlowUtils.IPv6, TABLE_ID));
 
         for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
             OfOverlayContext ofc = ep.getAugmentation(OfOverlayContext.class);
@@ -98,49 +99,42 @@ public class PortSecurity extends FlowTable {
     }
 
     private Flow allowFromPort(NodeConnectorId port) {
-        FlowId flowid = new FlowId(new StringBuilder()
-                .append("allow|")
-                .append(port.getValue())
-                .toString());
+        Match match = new MatchBuilder()
+                .setInPort(port)
+                .build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "allow", match);
         FlowBuilder flowb = base()
                 .setId(flowid)
                 .setPriority(Integer.valueOf(200))
-                .setMatch(new MatchBuilder()
-                        .setInPort(port)
-                        .build())
+                .setMatch(match)
                 .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()));
         return flowb.build();
     }
 
     private Flow allowFromExternalPort(NodeConnectorId port) {
-        FlowId flowid = new FlowId(new StringBuilder()
-                .append("allowExternal|")
-                .append(port.getValue())
-                .toString());
+        Match match = new MatchBuilder()
+                .setInPort(port)
+                .build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "allowExternal", match);
         FlowBuilder flowb = base()
                 .setId(flowid)
                 .setPriority(Integer.valueOf(200))
-                .setMatch(new MatchBuilder()
-                        .setInPort(port)
-                        .build())
+                .setMatch(match)
                 .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_INGRESS_NAT()));
         return flowb.build();
     }
 
     private Flow l2flow(Endpoint ep, OfOverlayContext ofc, Integer priority) {
-        FlowId flowid = new FlowId(new StringBuilder()
-                .append(ofc.getNodeConnectorId().getValue())
-                .append("|")
-                .append(ep.getMacAddress().getValue())
-                .toString());
+        Match match = new MatchBuilder()
+                .setEthernetMatch(
+                        FlowUtils.ethernetMatch(ep.getMacAddress(), null, null))
+                .setInPort(ofc.getNodeConnectorId())
+                .build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "L2", match);
         FlowBuilder flowb = base()
                 .setPriority(priority)
                 .setId(flowid)
-                .setMatch(new MatchBuilder()
-                        .setEthernetMatch(FlowUtils.ethernetMatch(ep.getMacAddress(),
-                                null, null))
-                        .setInPort(ofc.getNodeConnectorId())
-                        .build())
+                .setMatch(match)
                 .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()));
 
         return flowb.build();
@@ -154,23 +148,19 @@ public class PortSecurity extends FlowTable {
         String ikey = "255.255.255.255/32";
         Layer3Match m = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build();
 
-        FlowId flowid = new FlowId(new StringBuilder()
-                .append(ofc.getNodeConnectorId().getValue())
-                .append("|")
-                .append(ep.getMacAddress().getValue())
-                .append("|dhcp|")
-                .append(etherType)
-                .toString());
+        Match match = new MatchBuilder()
+                .setEthernetMatch(
+                        FlowUtils.ethernetMatch(ep.getMacAddress(),
+                        null,
+                        etherType))
+                .setLayer3Match(m)
+                .setInPort(ofc.getNodeConnectorId())
+                .build();
+        FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "dhcp", match);
         Flow flow = base()
                 .setPriority(priority)
                 .setId(flowid)
-                .setMatch(new MatchBuilder()
-                        .setEthernetMatch(FlowUtils.ethernetMatch(ep.getMacAddress(),
-                                null,
-                                etherType))
-                        .setLayer3Match(m)
-                        .setInPort(ofc.getNodeConnectorId())
-                        .build())
+                .setMatch(match)
                 .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()))
                 .build();
 
@@ -212,25 +202,19 @@ public class PortSecurity extends FlowTable {
             } else {
                 continue;
             }
-            FlowId flowid = new FlowId(new StringBuilder()
-                    .append(ofc.getNodeConnectorId().getValue())
-                    .append("|")
-                    .append(ep.getMacAddress().getValue())
-                    .append("|")
-                    .append(ikey)
-                    .append("|")
-                    .append(etherType)
-                    .toString());
+            Match match = new MatchBuilder()
+                    .setEthernetMatch(
+                            FlowUtils.ethernetMatch(ep.getMacAddress(),
+                            null,
+                            etherType))
+                    .setLayer3Match(m)
+                    .setInPort(ofc.getNodeConnectorId())
+                    .build();
+            FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "L3", match);
             Flow flow = base()
                     .setPriority(priority)
                     .setId(flowid)
-                    .setMatch(new MatchBuilder()
-                            .setEthernetMatch(FlowUtils.ethernetMatch(ep.getMacAddress(),
-                                    null,
-                                    etherType))
-                            .setLayer3Match(m)
-                            .setInPort(ofc.getNodeConnectorId())
-                            .build())
+                    .setMatch(match)
                     .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()))
                     .build();
 
old mode 100644 (file)
new mode 100755 (executable)
index f7d22ac..34f3827
@@ -32,6 +32,7 @@ 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;
@@ -65,7 +66,7 @@ public class SourceMapper extends FlowTable {
 
     public SourceMapper(OfContext ctx, short tableId) {
         super(ctx);
-        this.TABLE_ID=tableId;
+        TABLE_ID = tableId;
     }
 
     @Override
@@ -76,7 +77,7 @@ 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
         Map<EndpointKey, EndpointL3> l3EpWithNatByL2Key = ctx.getEndpointManager().getL3EpWithNatByL2Key();
@@ -154,12 +155,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);
 
@@ -176,9 +171,11 @@ 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())
+            .setMatch(match)
             .setInstructions(instructions(applyActionIns(fdReg), gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
         return flowb.build();
     }
@@ -192,19 +189,6 @@ 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);
 
@@ -223,9 +207,11 @@ 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(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
@@ -244,20 +230,6 @@ public class SourceMapper extends FlowTable {
         int cgId = epFwdCtxOrds.getCgId();
         int tunnelId = epFwdCtxOrds.getTunnelId();
 
-        FlowId flowid = new FlowId(new StringBuilder().append(ncId.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));
@@ -265,12 +237,13 @@ public class SourceMapper extends FlowTable {
         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(ncId)
-                        .build())
+            .setMatch(match)
             .setInstructions(
                     instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg,tunIdAction),
                             gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
index b4e98079a1a6b569c222abe829e52ca4e01f145f..fb6548cd87dc1e8a64521479b547d1087bca2d9c 100755 (executable)
@@ -8,11 +8,8 @@
 \r
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
 \r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Objects;\r
-\r
+import com.google.common.collect.ImmutableList;\r
+import com.google.common.collect.ImmutableMap;\r
 import org.junit.Before;\r
 import org.junit.Test;\r
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;\r
@@ -22,8 +19,10 @@ import org.opendaylight.groupbasedpolicy.resolver.EgKey;
 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;\r
@@ -51,22 +50,32 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.RuleBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 \r
-import com.google.common.collect.ImmutableList;\r
-import com.google.common.collect.ImmutableMap;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Objects;\r
 \r
-import static org.junit.Assert.*;\r
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotEquals;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;\r
 \r
 public class PolicyEnforcerTest extends FlowTableTest {\r
     protected static final Logger LOG =\r
@@ -113,8 +122,9 @@ public class PolicyEnforcerTest extends FlowTableTest {
         HashMap<String, Flow> flowMap = new HashMap<>();\r
         for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {\r
             flowMap.put(f.getId().getValue(), f);\r
-            if (f.getId().getValue().indexOf("intraallow") == 0)\r
+            if (isAllowSameEpg(f)) {\r
                 count += 1;\r
+            }\r
         }\r
         assertEquals(1, count);\r
         assertEquals(3, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());\r
@@ -185,7 +195,7 @@ public class PolicyEnforcerTest extends FlowTableTest {
         HashMap<String, Flow> flowMap = new HashMap<>();\r
         for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) {\r
             flowMap.put(f.getId().getValue(), f);\r
-            if (f.getId().getValue().indexOf("intraallow") == 0) {\r
+            if (isAllowSameEpg(f)) {\r
                 count += 1;\r
             } else if (f.getMatch() != null &&\r
                        Objects.equals(tunnelId, f.getMatch().getInPort())) {\r
@@ -332,4 +342,40 @@ public class PolicyEnforcerTest extends FlowTableTest {
         fm = dosync(flowMap);\r
         assertEquals(numberOfFlows, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow().size());\r
     }\r
+\r
+    private boolean isAllowSameEpg(Flow flow) {\r
+        // flow has to have exactly 2 registers set, namely NxmNxReg0 and NxmNxReg2\r
+        // (these register values don't have to be equal)\r
+        boolean res = false;\r
+        if (flow != null && flow.getMatch() != null) {\r
+            GeneralAugMatchNodesNodeTableFlow genAug =\r
+                    flow.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);\r
+            if (genAug != null) {\r
+                List<ExtensionList> extensions = genAug.getExtensionList();\r
+                if (extensions != null && extensions.size() == 2) {\r
+                    Long reg0 = null;\r
+                    Long reg2 = null;\r
+                    for (ExtensionList extensionList : extensions) {\r
+                        Class<? extends ExtensionKey> extensionKey = extensionList.getExtensionKey();\r
+                        Extension extension = extensionList.getExtension();\r
+                        if (extensionKey != null && extension != null) {\r
+                            NxAugMatchNodesNodeTableFlow nxAugMatch =\r
+                                    extension.getAugmentation(NxAugMatchNodesNodeTableFlow.class);\r
+                            if (nxAugMatch != null && nxAugMatch.getNxmNxReg() != null) {\r
+                                if (extensionKey.equals(NxmNxReg0Key.class)) {\r
+                                    reg0 = nxAugMatch.getNxmNxReg().getValue();\r
+                                } else if (extensionKey.equals(NxmNxReg2Key.class)) {\r
+                                    reg2 = nxAugMatch.getNxmNxReg().getValue();\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                    if (reg0 != null && reg2 != null) {\r
+                        res = true;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return res;\r
+    }\r
 }\r