Implement SFC integration
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / PolicyEnforcer.java
index 8c5c8a7e09a6e6f3747d6f9973cb67d019fad010..87a31eaf2e53b642ec7d6ad1f76611ed131b1b04 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -28,6 +28,7 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassificationResult;
@@ -46,6 +47,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 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.ClassifierDefinitionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
@@ -64,7 +66,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
+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.NxmNxReg7;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -76,8 +80,8 @@ import com.google.common.collect.Ordering;
  * unless specifically allowed by policy
  */
 public class PolicyEnforcer extends FlowTable {
-    protected static final Logger LOG =
-            LoggerFactory.getLogger(PolicyEnforcer.class);
+
+    protected static final Logger LOG = LoggerFactory.getLogger(PolicyEnforcer.class);
 
     public static final short TABLE_ID = 3;
 
@@ -95,51 +99,63 @@ public class PolicyEnforcer extends FlowTable {
 
         flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
 
-        flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(nodeId));
+        NodeConnectorId tunPort = SwitchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class);
+        if (tunPort != null) {
+            flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(tunPort));
+        }
 
         HashSet<CgPair> visitedPairs = new HashSet<>();
 
+        // Used for ARP flows
+        Set<Integer> fdIds = new HashSet<>();
+
         for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
             for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
                 Set<EgKey> peers = policyInfo.getPeers(srcEpgKey);
                 for (EgKey dstEpgKey : peers) {
                     for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(dstEpgKey)) {
                         // mEPG ordinals
-                        EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, srcEp);
-                        EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dstEp);
+                        EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
+                                policyInfo, srcEp);
+                        EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
+                                policyInfo, dstEp);
                         int dcgId = dstEpFwdCxtOrds.getCgId();
                         int depgId = dstEpFwdCxtOrds.getEpgId();
                         int scgId = srcEpFwdCxtOrds.getCgId();
                         int sepgId = srcEpFwdCxtOrds.getEpgId();
+                        NetworkElements netElements = new NetworkElements(srcEp, dstEp, nodeId, ctx, policyInfo);
+                        fdIds.add(srcEpFwdCxtOrds.getFdId());
 
                         List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(srcEp);
                         ConditionGroup scg = policyInfo.getEgCondGroup(srcEpgKey, conds);
                         conds = ctx.getEndpointManager().getCondsForEndpoint(dstEp);
                         ConditionGroup dcg = policyInfo.getEgCondGroup(dstEpgKey, conds);
 
+                        Policy policy = policyInfo.getPolicy(dstEpgKey, srcEpgKey);
+                        List<RuleGroup> rgs = policy.getRules(dcg, scg);
                         CgPair p = new CgPair(depgId, sepgId, dcgId, scgId);
                         if (visitedPairs.contains(p))
                             continue;
                         visitedPairs.add(p);
-                        syncPolicy(flowMap, nodeId, policyInfo,
-                                p, dstEpgKey, srcEpgKey, dcg, scg);
+                        syncPolicy(flowMap, netElements, rgs, p);
 
-                        //Reverse
+                        // Reverse
+                        policy = policyInfo.getPolicy(srcEpgKey, dstEpgKey);
+                        rgs = policy.getRules(scg, dcg);
                         p = new CgPair(sepgId, depgId, scgId, dcgId);
                         if (visitedPairs.contains(p))
                             continue;
                         visitedPairs.add(p);
-                        syncPolicy(flowMap, nodeId, policyInfo,
-                                p, srcEpgKey, dstEpgKey, scg, dcg);
+                        syncPolicy(flowMap, netElements, rgs, p);
                     }
                 }
             }
         }
 
         // Allow same EPG
-//        Set<Endpoint> visitedEps = new HashSet<>();
+        // Set<Endpoint> visitedEps = new HashSet<>();
         for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
-//            visitedEps.add(srcEp);
+            // visitedEps.add(srcEp);
             for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
 
                 IndexedTenant tenant = ctx.getPolicyResolver().getTenant(srcEpgKey.getTenantId());
@@ -149,12 +165,14 @@ public class PolicyEnforcer extends FlowTable {
                 if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
                     for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(srcEpgKey)) {
                         // mEPG ordinals
-//                        if(visitedEps.contains(dstEp)) {
-//                            continue;
-//                        }
-//                        visitedEps.add(dstEp);
-                        EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, srcEp);
-                        EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dstEp);
+                        // if(visitedEps.contains(dstEp)) {
+                        // continue;
+                        // }
+                        // visitedEps.add(dstEp);
+                        EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
+                                policyInfo, srcEp);
+                        EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
+                                policyInfo, dstEp);
                         int depgId = dstEpFwdCxtOrds.getEpgId();
                         int sepgId = srcEpFwdCxtOrds.getEpgId();
                         flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(sepgId, depgId));
@@ -164,63 +182,70 @@ public class PolicyEnforcer extends FlowTable {
             }
         }
 
+        // Write ARP flows per flood domain.
+        for (Integer fdId : fdIds) {
+            flowMap.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
+        }
+    }
+
+    private Flow createArpFlow(Integer fdId) {
+
+        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)));
+
+        Flow flow = base().setPriority(priority)
+            .setId(flowid)
+            .setMatch(mb.build())
+            .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))))
+            .build();
+        return flow;
     }
 
     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)));
-            FlowBuilder flow = base()
-                    .setId(flowId)
-                    .setMatch(mb.build())
-                    .setPriority(65000)
-                    .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
-            return flow.build();
+
+        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)));
+        FlowBuilder flow = base().setId(flowId)
+            .setMatch(mb.build())
+            .setPriority(65000)
+            .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
+        return flow.build();
     }
 
-    private Flow allowFromTunnel(NodeId nodeId) {
-        NodeConnectorId tunPort =
-                ctx.getSwitchManager().getTunnelPort(nodeId);
-        if (tunPort == null)
-            return null;
+    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)));
-        FlowBuilder flow = base()
-                .setId(flowId)
-                .setMatch(mb.build())
-                .setPriority(65000)
-                .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
+        MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
+        addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
+        FlowBuilder flow = base().setId(flowId)
+            .setMatch(mb.build())
+            .setPriority(65000)
+            .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
         return flow.build();
 
     }
 
-    private void syncPolicy(FlowMap flowMap, NodeId nodeId,
-            PolicyInfo policyInfo,
-            CgPair p, EgKey sepg, EgKey depg,
-            ConditionGroup scg, ConditionGroup dcg)
-            throws Exception {
-        // XXX - TODO raise an exception for rules between the same
-        // endpoint group that are asymmetric
-        Policy policy = policyInfo.getPolicy(sepg, depg);
-        List<RuleGroup> rgs = policy.getRules(scg, dcg);
-
+    private void syncPolicy(FlowMap flowMap, NetworkElements netElements, List<RuleGroup> rgs, CgPair p) {
         int priority = 65000;
         for (RuleGroup rg : rgs) {
             TenantId tenantId = rg.getContractTenant().getId();
             IndexedTenant tenant = ctx.getPolicyResolver().getTenant(tenantId);
             for (Rule r : rg.getRules()) {
-                syncDirection(flowMap, nodeId, tenant,
-                        p, r, Direction.In, priority);
-                syncDirection(flowMap, nodeId, tenant,
-                        p, r, Direction.Out, priority);
+                syncDirection(flowMap, netElements, tenant, p, r, Direction.In, priority);
+                syncDirection(flowMap, netElements, tenant, p, r, Direction.Out, priority);
 
                 priority -= 1;
             }
@@ -232,25 +257,23 @@ public class PolicyEnforcer extends FlowTable {
      * determined first by the value of the order parameter, with the lower
      * order actions being applied first; for Actions with either the same order
      * or no order, ordering is lexicographical by name.
-     *
      */
     private static class ActionRefComparator implements Comparator<ActionRef> {
+
         public static final ActionRefComparator INSTANCE = new ActionRefComparator();
 
         @Override
         public int compare(ActionRef arg0, ActionRef arg1) {
             return ComparisonChain.start()
-                    .compare(arg0.getOrder(), arg1.getOrder(),
-                            Ordering.natural().nullsLast())
-                    .compare(arg0.getName().getValue(), arg1.getName().getValue(),
-                            Ordering.natural().nullsLast())
-                    .result();
+                .compare(arg0.getOrder(), arg1.getOrder(), Ordering.natural().nullsLast())
+                .compare(arg0.getName().getValue(), arg1.getName().getValue(), Ordering.natural().nullsLast())
+                .result();
         }
 
     }
 
-    private void syncDirection(FlowMap flowMap, NodeId nodeId, IndexedTenant contractTenant,
-            CgPair cgPair, Rule rule, Direction direction, int priority) {
+    private void syncDirection(FlowMap flowMap, NetworkElements netElements, IndexedTenant contractTenant, CgPair cgPair, Rule rule,
+            Direction direction, int priority) {
         /*
          * Create the ordered action list. The implicit action is "allow", and
          * is therefore always in the list
@@ -259,8 +282,9 @@ public class PolicyEnforcer extends FlowTable {
          * incorporating operational policy for actions
          */
 
-        //TODO: can pass Comparator ActionRefComparator to List constructor, rather than referencing in sort
-        List<ActionBuilder> abl = new ArrayList<ActionBuilder>();
+        // TODO: can pass Comparator ActionRefComparator to List constructor, rather than
+        // referencing in sort
+        List<ActionBuilder> actionBuilderList = new ArrayList<ActionBuilder>();
         if (rule.getActionRef() != null) {
             /*
              * Pre-sort by references using order, then name
@@ -268,25 +292,23 @@ public class PolicyEnforcer extends FlowTable {
             List<ActionRef> arl = new ArrayList<ActionRef>(rule.getActionRef());
             Collections.sort(arl, ActionRefComparator.INSTANCE);
 
-            for (ActionRef ar : arl) {
-                ActionInstance ai = contractTenant.getAction(ar.getName());
-                if (ai == null) {
+            for (ActionRef actionRule : arl) {
+                ActionInstance actionInstance = contractTenant.getAction(actionRule.getName());
+                if (actionInstance == null) {
                     // XXX TODO fail the match and raise an exception
-                    LOG.warn("Action instance {} not found",
-                            ar.getName().getValue());
+                    LOG.warn("Action instance {} not found", actionRule.getName().getValue());
                     return;
                 }
-                Action act = SubjectFeatures.getAction(ai.getActionDefinitionId());
-                if (act == null) {
+                Action action = SubjectFeatures.getAction(actionInstance.getActionDefinitionId());
+                if (action == null) {
                     // XXX TODO fail the match and raise an exception
-                    LOG.warn("Action definition {} not found",
-                            ai.getActionDefinitionId().getValue());
+                    LOG.warn("Action definition {} not found", actionInstance.getActionDefinitionId().getValue());
                     return;
                 }
 
                 Map<String, Object> params = new HashMap<>();
-                if (ai.getParameterValue() != null) {
-                    for (ParameterValue v : ai.getParameterValue()) {
+                if (actionInstance.getParameterValue() != null) {
+                    for (ParameterValue v : actionInstance.getParameterValue()) {
                         if (v.getName() == null)
                             continue;
                         if (v.getIntValue() != null) {
@@ -299,30 +321,62 @@ public class PolicyEnforcer extends FlowTable {
                 /*
                  * Convert the GBP Action to one or more OpenFlow Actions
                  */
-                abl = act.updateAction(abl, params, ar.getOrder());
+                actionBuilderList = action.updateAction(actionBuilderList, params, actionRule.getOrder(),netElements);
             }
-        }
-        else {
+        } else {
             Action act = SubjectFeatures.getAction(AllowAction.DEFINITION.getId());
-            abl = act.updateAction(abl, new HashMap<String, Object>(), 0);
+            actionBuilderList = act.updateAction(actionBuilderList, new HashMap<String, Object>(), 0, netElements);
         }
 
+        Map<String, ParameterValue> paramsFromClassifier = new HashMap<>();
+        Set<ClassifierDefinitionId> classifiers = new HashSet<>();
         for (ClassifierRef cr : rule.getClassifierRef()) {
-            if (cr.getDirection() != null &&
-                    !cr.getDirection().equals(Direction.Bidirectional) &&
-                    !cr.getDirection().equals(direction)) {
+            if (cr.getDirection() != null && !cr.getDirection().equals(Direction.Bidirectional)
+                    && !cr.getDirection().equals(direction)) {
                 continue;
             }
 
-            StringBuilder idb = new StringBuilder();
             // XXX - TODO - implement connection tracking (requires openflow
             // extension and data plane support - in 2.4. Will need to handle
             // case where we are working with mix of nodes.
 
-            MatchBuilder baseMatch = new MatchBuilder();
+            ClassifierInstance ci = contractTenant.getClassifier(cr.getName());
+            if (ci == null) {
+                // XXX TODO fail the match and raise an exception
+                LOG.warn("Classifier instance {} not found", cr.getName().getValue());
+                return;
+            }
+            Classifier cfier = SubjectFeatures.getClassifier(ci.getClassifierDefinitionId());
+            if (cfier == null) {
+                // XXX TODO fail the match and raise an exception
+                LOG.warn("Classifier definition {} not found", ci.getClassifierDefinitionId().getValue());
+                return;
+            }
+            classifiers.add(new ClassifierDefinitionId(ci.getClassifierDefinitionId()));
+            for (ParameterValue v : ci.getParameterValue()) {
 
-            if (direction.equals(Direction.In)) {
-                idb.append(cgPair.sepg)
+                if (v.getIntValue() != null) {
+                    paramsFromClassifier.put(v.getName().getValue(), v);
+                } else if (v.getStringValue() != null) {
+                    paramsFromClassifier.put(v.getName().getValue(), v);
+                } else if (v.getRangeValue() != null) {
+                    paramsFromClassifier.put(v.getName().getValue(), v);
+                }
+            }
+        }
+        List<Map<String, ParameterValue>> derivedParamsByName = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(paramsFromClassifier);
+
+        for (Map<String, ParameterValue> params : derivedParamsByName) {
+            for (ClassifierDefinitionId clDefId : classifiers) {
+                Classifier classifier = SubjectFeatures.getClassifier(clDefId);
+                StringBuilder idb = new StringBuilder();
+                // XXX - TODO - implement connection tracking (requires openflow
+                // extension and data plane support - in 2.4. Will need to handle
+                // case where we are working with mix of nodes.
+
+                MatchBuilder baseMatch = new MatchBuilder();
+                if (direction.equals(Direction.In)) {
+                    idb.append(cgPair.sepg)
                         .append("|")
                         .append(cgPair.scgId)
                         .append("|")
@@ -331,13 +385,12 @@ public class PolicyEnforcer extends FlowTable {
                         .append(cgPair.dcgId)
                         .append("|")
                         .append(priority);
-                addNxRegMatch(baseMatch,
-                        RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.sepg)),
-                        RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.scgId)),
-                        RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.depg)),
-                        RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.dcgId)));
-            } else {
-                idb.append(cgPair.depg)
+                    addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.sepg)),
+                            RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.scgId)),
+                            RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.depg)),
+                            RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.dcgId)));
+                } else {
+                    idb.append(cgPair.depg)
                         .append("|")
                         .append(cgPair.dcgId)
                         .append("|")
@@ -346,46 +399,18 @@ public class PolicyEnforcer extends FlowTable {
                         .append(cgPair.scgId)
                         .append("|")
                         .append(priority);
-                addNxRegMatch(baseMatch,
-                        RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.depg)),
-                        RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.dcgId)),
-                        RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.sepg)),
-                        RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.scgId)));
-            }
-
-            ClassifierInstance ci = contractTenant.getClassifier(cr.getName());
-            if (ci == null) {
-                // XXX TODO fail the match and raise an exception
-                LOG.warn("Classifier instance {} not found",
-                        cr.getName().getValue());
-                return;
-            }
-            Classifier cfier = SubjectFeatures
-                    .getClassifier(ci.getClassifierDefinitionId());
-            if (cfier == null) {
-                // XXX TODO fail the match and raise an exception
-                LOG.warn("Classifier definition {} not found",
-                        ci.getClassifierDefinitionId().getValue());
-                return;
-            }
+                    addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.depg)),
+                            RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.dcgId)),
+                            RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.sepg)),
+                            RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.scgId)));
+                }
 
-            Map<String,ParameterValue> params = new HashMap<>();
-            for (ParameterValue v : ci.getParameterValue()) {
+                List<MatchBuilder> matches = new ArrayList<>();
+                matches.add(baseMatch);
 
-                if (v.getIntValue() != null) {
-                    params.put(v.getName().getValue(), v);
-                } else if (v.getStringValue() != null) {
-                    params.put(v.getName().getValue(), v);
-                } else if (v.getRangeValue() != null) {
-                    params.put(v.getName().getValue(), v);
-                }
-            }
-            List<Map<String, ParameterValue>> derivedParams = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(params);
-            for (Map<String, ParameterValue> flowParams : derivedParams) {
-                List<MatchBuilder> matches = Collections.singletonList(new MatchBuilder(baseMatch.build()));
-                ClassificationResult result = cfier.updateMatch(matches, flowParams);
-                if(!result.isSuccessfull()) {
-                    //TODO consider different handling.
+                ClassificationResult result = classifier.updateMatch(matches, params);
+                if (!result.isSuccessfull()) {
+                    // TODO consider different handling.
                     throw new IllegalArgumentException(result.getErrorMessage());
                 }
                 String baseId = idb.toString();
@@ -393,13 +418,11 @@ public class PolicyEnforcer extends FlowTable {
                 for (MatchBuilder match : result.getMatchBuilders()) {
                     Match m = match.build();
                     FlowId flowId = new FlowId(baseId + "|" + m.toString());
-                flow.setMatch(m)
+                    flow.setMatch(m)
                         .setId(flowId)
                         .setPriority(Integer.valueOf(priority))
-                        .setInstructions(instructions(applyActionIns(abl)));
-                flowMap.writeFlow(nodeId, TABLE_ID, flow.build());
-
-
+                        .setInstructions(instructions(applyActionIns(actionBuilderList)));
+                    flowMap.writeFlow(netElements.getNodeId(), TABLE_ID, flow.build());
                 }
             }
         }
@@ -407,6 +430,7 @@ public class PolicyEnforcer extends FlowTable {
 
     @Immutable
     private static class CgPair {
+
         private final int sepg;
         private final int depg;
         private final int scgId;
@@ -451,4 +475,49 @@ public class PolicyEnforcer extends FlowTable {
             return true;
         }
     }
+
+    public class NetworkElements {
+        Endpoint src;
+        Endpoint dst;
+        NodeId nodeId;
+        EndpointFwdCtxOrdinals srcOrds;
+        EndpointFwdCtxOrdinals dstOrds;
+
+        public NetworkElements(Endpoint src, Endpoint dst, NodeId nodeId, OfContext ctx, PolicyInfo policyInfo) throws Exception {
+            this.src=src;
+            this.dst=dst;
+            this.nodeId = nodeId;
+            this.srcOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, src);
+            this.dstOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dst);
+        }
+
+
+
+        public EndpointFwdCtxOrdinals getSrcOrds() {
+            return srcOrds;
+        }
+
+
+
+        public EndpointFwdCtxOrdinals getDstOrds() {
+            return dstOrds;
+        }
+
+
+        public Endpoint getSrc() {
+            return src;
+        }
+
+
+        public Endpoint getDst() {
+            return dst;
+        }
+
+
+        public NodeId getNodeId() {
+            return nodeId;
+        }
+
+
+    }
 }