add rest of sfc flows
authorSam Hague <shague@redhat.com>
Wed, 11 Nov 2015 04:54:04 +0000 (23:54 -0500)
committerSam Hague <shague@redhat.com>
Wed, 11 Nov 2015 04:54:04 +0000 (23:54 -0500)
Change-Id: I44629e889705c4e7f6a21c3655addee9670bc8c5
Signed-off-by: Sam Hague <shague@redhat.com>
openstack/net-virt-sfc/impl/pom.xml
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/ISfcClassifierService.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/services/SfcClassifierService.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java
openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/InstructionUtils.java

index 3bd7e21e281bd2e596bdbc28b6cdf25f711f93d8..147c80673ad106baec2f5300329b4699d8905d5c 100644 (file)
@@ -48,11 +48,16 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>openstack.net-virt-providers</artifactId>
       <version>${project.version}</version>
     </dependency>
-       <dependency>
+    <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>southbound-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>southbound-impl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>utils.mdsal-utils</artifactId>
index e0a9dfba6e3bf89b117a50b2d58c7b29596d0bb0..626b1cceaca25b63781d6210f60e0b32d1b8cb4d 100644 (file)
@@ -13,4 +13,14 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.cont
 public interface ISfcClassifierService {
     void programIngressClassifier(long dataPathId, String ruleName, Matches matches,
                                   NshUtils nshHeader, long vxGpeOfPort, boolean write);
+
+    void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write);
+
+    void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                  int tunnelOfPort, int tunnelId, short gotoTableId, boolean write);
+
+    void programEgressClassifier2(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                  int tunnelOfPort, int tunnelId, boolean write);
+
+    void program_sfEgress(long dataPathId, int dstPort, boolean write);
 }
index 96b240cb07bc5c277af2540ddf38d86a5038294f..944a4824c688c8cb946f6027c589825e22f5f3f2 100644 (file)
@@ -42,4 +42,24 @@ public class SfcClassifierService extends AbstractServiceInstance implements Con
     public void programIngressClassifier(long dataPathId, String ruleName, Matches matches, NshUtils nshHeader, long vxGpeOfPort, boolean write) {
 
     }
+
+    @Override
+    public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
+
+    }
+
+    @Override
+    public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi, int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
+
+    }
+
+    @Override
+    public void programEgressClassifier2(long dataPathId, long vxGpeOfPort, long nsp, short nsi, int tunnelOfPort, int tunnelId, boolean write) {
+
+    }
+
+    @Override
+    public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
+
+    }
 }
index 258b6b4255eaa6a031f1b5dd0a4cf74cca872ec9..a452442093d3ab99c916bd91ce49bd0921de4471 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.SfcUtils;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService;
+import org.opendaylight.ovsdb.southbound.SouthboundConstants;
 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
@@ -52,6 +53,9 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider
     private volatile NodeCacheManager nodeCacheManager;
     private volatile Southbound southbound;
     private volatile ISfcClassifierService sfcClassifierService;
+    private static final short SFC_TABLE = 150;
+    private static final int GPE_PORT = 6633;
+    private static final String NETWORK_TYPE_VXLAN = "vxlan";
 
     public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
         this.sfcClassifierService = sfcClassifierService;
@@ -126,6 +130,7 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider
         handleIngressClassifier(rsp, entry);
         //handleEgressClassifier();
         //handleSfLoopback();
+        //sfArp and ingressSfLoopback uses linux stack
     }
 
     private void handleIngressClassifier(RenderedServicePath rsp, Ace entry) {
@@ -154,12 +159,17 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider
             if (ovsdbBridgeAugmentation == null) {
                 continue;
             }
-            long vxGpeOfPort = southbound.getOFPort(bridgeNode, VXGPE);
+            long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
             if (vxGpeOfPort == 0L) {
                 LOG.warn("programAclEntry: Could not identify tunnel port {} -> OF ({}) on {}",
                         VXGPE, vxGpeOfPort, bridgeNode);
                 continue;
             }
+            long dataPathId = southbound.getDataPathId(bridgeNode);
+            if (dataPathId == 0L) {
+                LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
+                continue;
+            }
 
             // Find the first Hop within an RSP.
             // The classifier flow needs to send all matched traffic to this first hop SFF.
@@ -173,10 +183,11 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider
 
             NshUtils nshHeader = new NshUtils();
             nshHeader.setNshMetaC1(NshUtils.convertIpAddressToLong(new Ipv4Address(TUNNEL_DST)));
-            nshHeader.setNshMetaC2(Long.parseLong(TUNNEL_VNID));
+            nshHeader.setNshMetaC2(Long.parseLong(TUNNEL_VNID)); // get from register //get from
             nshHeader.setNshNsp(rsp.getPathId());
 
             RenderedServicePathHop firstHop = pathHopList.get(0);
+            RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
             nshHeader.setNshNsi(firstHop.getServiceIndex());
             // workaround: bypass sff and got directly to sf
             //nshHeader.setNshTunIpDst(firstRspHop.getIp().getIpv4Address());
@@ -185,9 +196,22 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider
             nshHeader.setNshTunUdpPort(firstRspHop.getPort());
             LOG.debug("handleIngressClassifier: NSH Header = {}", nshHeader);
 
-            sfcClassifierService.programIngressClassifier(
-                    southbound.getDataPathId(bridgeNode), entry.getRuleName(),
-                    matches, nshHeader, vxGpeOfPort, true);
+            sfcClassifierService.programIngressClassifier(dataPathId, entry.getRuleName(), matches,
+                    nshHeader, vxGpeOfPort, true);
+
+            sfcClassifierService.program_sfEgress(dataPathId, GPE_PORT, true);
+            //not needed if ip route and arp can be added to stack
+            //sfcClassifierService.program_sfIngress(dataPathId, true);
+            //sfcClassifierService.program_sfArp(dataPathId, true);
+
+            short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
+            long tunnelOfPort = getTunnelOfPort(bridgeNode, VXGPE);
+            sfcClassifierService.programEgressClassifier1(dataPathId, vxGpeOfPort, rsp.getPathId(),
+                    lastServiceindex, (int)tunnelOfPort, 0, (short)0, true);
+            sfcClassifierService.programEgressClassifier2(dataPathId, vxGpeOfPort, rsp.getPathId(),
+                    lastServiceindex, (int) tunnelOfPort, 0, true);
+
+            sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
         }
     }
 
@@ -199,7 +223,6 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider
 
     }
 
-
     private RenderedServicePath getRenderedServicePath (Ace entry) {
         RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
         LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
@@ -251,8 +274,29 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider
         return rsp;
     }
 
-    public Long getOFPort(Node bridgeNode, String portName) {
-        Long ofPort = 0L;
+    // loop through all ports looking for vxlan types, skip vxgpe, keep the rest
+    // first pass we only have two tunnels: one for normal vxlan and the other for gpe
+    // so just return the first non-gpe vxlan port
+    private long getTunnelOfPort(Node bridgeNode, String vxGpePortName) {
+        long port = 0L;
+        List<OvsdbTerminationPointAugmentation> ovsdbTerminationPointAugmentations =
+                southbound.getTerminationPointsOfBridge(bridgeNode);
+        if (!ovsdbTerminationPointAugmentations.isEmpty()) {
+            for (OvsdbTerminationPointAugmentation terminationPointAugmentation : ovsdbTerminationPointAugmentations) {
+                if (terminationPointAugmentation.getInterfaceType() ==
+                        SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(NETWORK_TYPE_VXLAN)) {
+                    if (!terminationPointAugmentation.getName().equals(vxGpePortName)) {
+                        port = terminationPointAugmentation.getOfport();
+                        break;
+                    }
+                }
+            }
+        }
+        return port;
+    }
+
+    private long getOFPort(Node bridgeNode, String portName) {
+        long ofPort = 0L;
         OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
         if (port != null) {
             ofPort = southbound.getOFPort(port);
index 44be094fd7b1b708db21f968a2d11748de55bd25..0c00852e1f4ba89433d16419a827453e17bc5ae5 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services;
 
 import com.google.common.collect.Lists;
 import java.math.BigInteger;
+import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
@@ -18,6 +19,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceEth;
@@ -45,7 +47,8 @@ import org.slf4j.LoggerFactory;
 
 public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface, ISfcClassifierService {
     private static final Logger LOG = LoggerFactory.getLogger(SfcClassifierService.class);
-    private static final short SFC_TABLE = 10;
+    private static final short TABLE_0 = 0;
+    private static final short UDP_SHORT = 17;
 
     public SfcClassifierService(Service service) {
         super(service);
@@ -71,22 +74,30 @@ public class SfcClassifierService extends AbstractServiceInstance implements Con
 
         MatchBuilder matchBuilder = buildMatch(matches);
         flowBuilder.setMatch(matchBuilder.build());
-        MatchUtils.addNxRegMatch(matchBuilder,
-                new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL));
+        flowBuilder.setMatch(MatchUtils.addNxRegMatch(
+                matchBuilder,
+                new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
 
-        String flowId = "sfcClass_" + ruleName;// + "_" + nshHeader.getNshNsp();
+        String flowId = "sfcIngressClass_" + ruleName;// + "_" + nshHeader.getNshNsp();
         flowBuilder.setId(new FlowId(flowId));
         FlowKey key = new FlowKey(new FlowId(flowId));
         flowBuilder.setBarrier(true);
-        flowBuilder.setTableId(SFC_TABLE);
+        flowBuilder.setTableId(getTable());
         flowBuilder.setKey(key);
         flowBuilder.setFlowName(flowId);
         flowBuilder.setHardTimeout(0);
         flowBuilder.setIdleTimeout(0);
 
         if (write) {
-            List<Action> actionList = getNshAction(nshHeader);
             ActionBuilder ab = new ActionBuilder();
+            List<Action> actionList = new ArrayList<>();
+
+            ab.setAction(ActionUtils.nxMoveTunIdtoNshc2());
+            ab.setOrder(actionList.size());
+            ab.setKey(new ActionKey(actionList.size()));
+            actionList.add(ab.build());
+
+            getNshAction(nshHeader, actionList);
 
             ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
             ab.setOrder(actionList.size());
@@ -112,7 +123,185 @@ public class SfcClassifierService extends AbstractServiceInstance implements Con
         }
     }
 
-    private List<Action> getNshAction(NshUtils header) {
+    @Override
+    public void programSfcTable(long dataPathId, long vxGpeOfPort, short goToTableId, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort).build());
+
+        String flowId = "sfcTable_" + vxGpeOfPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setPriority(1000);
+
+        if (write) {
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            InstructionBuilder ib =
+                    InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), goToTableId);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void programEgressClassifier1(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                         int tunnelOfPort, int tunnelId, short gotoTableId, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort).build());
+        flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nsp).build());
+        flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
+
+        String flowId = "sfcEgressClass1_" + vxGpeOfPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(TABLE_0);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            List<Action> actionList = Lists.newArrayList();
+
+            ActionBuilder ab = new ActionBuilder();
+            ab.setAction(ActionUtils.nxMoveNshc2ToTunId());
+            ab.setOrder(0);
+            ab.setKey(new ActionKey(0));
+            actionList.add(ab.build());
+
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+            InstructionBuilder ib = new InstructionBuilder();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            ib = InstructionUtils.createGotoTableInstructions(new InstructionBuilder(), getTable());
+            ib.setOrder(1);
+            ib.setKey(new InstructionKey(1));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void programEgressClassifier2(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
+                                         int tunnelOfPort, int tunnelId, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dataPathId, vxGpeOfPort).build());
+        flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nsp).build());
+        flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nsi).build());
+
+        String flowId = "sfcEgressClass2_" + vxGpeOfPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            List<Action> actionList = Lists.newArrayList();
+
+            ActionBuilder ab = new ActionBuilder();
+            ab.setAction(ActionUtils.nxResubmitAction(tunnelOfPort, TABLE_0));
+            ab.setOrder(0);
+            ab.setKey(new ActionKey(0));
+            actionList.add(ab.build());
+
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+            InstructionBuilder ib = new InstructionBuilder();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    @Override
+    public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createIpProtocolMatch(matchBuilder, UDP_SHORT);
+        flowBuilder.setMatch(MatchUtils.addLayer4Match(matchBuilder, UDP_SHORT, 0, dstPort).build());
+        flowBuilder.setMatch(MatchUtils.addNxRegMatch(
+                matchBuilder, new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build());
+
+        String flowId = "sfEgress_" + dstPort;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+            InstructionUtils.createLocalInstructions(ib, dataPathId);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            isb.setInstruction(instructions);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    private List<Action> getNshAction(NshUtils header, List<Action> actionList) {
         // Build the Actions to Add the NSH Header
         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nshC1Load =
                 ActionUtils.nxLoadNshc1RegAction(header.getNshMetaC1());
@@ -127,14 +316,19 @@ public class SfcClassifierService extends AbstractServiceInstance implements Con
         org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest =
                 ActionUtils.nxLoadTunIPv4Action(header.getNshTunIpDst().getValue(), false);
 
-        int count = 0;
-        List<Action> actionList = Lists.newArrayList();
-        actionList.add(new ActionBuilder().setOrder(count++).setAction(nshC1Load).build());
-        actionList.add(new ActionBuilder().setOrder(count++).setAction(nshC2Load).build());
-        actionList.add(new ActionBuilder().setOrder(count++).setAction(nspLoad).build());
-        actionList.add(new ActionBuilder().setOrder(count++).setAction(nsiLoad).build());
-        actionList.add(new ActionBuilder().setOrder(count++).setAction(loadChainTunDest).build());
-        actionList.add(new ActionBuilder().setOrder(count++).setAction(loadChainTunVnid).build());
+        int count = actionList.size();
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC1Load).build());
+        //actionList.add(new ActionBuilder()
+        // .setKey(new ActionKey(count)).setOrder(count++).setAction(nshC2Load).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(nspLoad).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(nsiLoad).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count++).setAction(loadChainTunDest).build());
+        actionList.add(new ActionBuilder()
+                .setKey(new ActionKey(count)).setOrder(count).setAction(loadChainTunVnid).build());
         return actionList;
     }
 
@@ -150,6 +344,10 @@ public class SfcClassifierService extends AbstractServiceInstance implements Con
                 MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
                 MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
                         aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
+            } else {
+                MatchUtils.createIpProtocolMatch(matchBuilder, aceIp.getProtocol());
+                MatchUtils.addLayer4Match(matchBuilder, aceIp.getProtocol().intValue(), 0,
+                        aceIp.getDestinationPortRange().getLowerPort().getValue().intValue());
             }
         } else if (matches.getAceType() instanceof AceEth) {
             AceEth aceEth = (AceEth) matches.getAceType();
index ab85bf3170aa7dd06b5d367e36a6404e4af29e48..c3b878c593b0a00402facf842654f15d68438114 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
@@ -58,6 +59,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._4.grouping.NxSetNshc4Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.SrcChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxArpShaCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc1CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc2CaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIdCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIpv4DstCaseBuilder;
@@ -261,35 +264,27 @@ public final class ActionUtils {
 
     public static Action nxMoveRegTunIdAction(Class<? extends NxmNxReg> src,
                                               boolean groupBucket) {
-        return nxMoveRegAction(new SrcNxRegCaseBuilder()
-                                    .setNxReg(src).build(),
-                               new DstNxTunIdCaseBuilder()
-                                   .setNxTunId(Boolean.TRUE).build(),
+        return nxMoveRegAction(new SrcNxRegCaseBuilder().setNxReg(src).build(),
+                               new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
                                31,
                                groupBucket);
     }
 
     public static Action nxMoveArpShaToArpThaAction() {
-        return nxMoveRegAction(new SrcNxArpShaCaseBuilder()
-                                   .setNxArpSha(Boolean.TRUE).build(),
-                               new DstNxArpThaCaseBuilder()
-                                   .setNxArpTha(Boolean.TRUE).build(),
+        return nxMoveRegAction(new SrcNxArpShaCaseBuilder().setNxArpSha(Boolean.TRUE).build(),
+                               new DstNxArpThaCaseBuilder().setNxArpTha(Boolean.TRUE).build(),
                                47, false);
     }
 
     public static Action nxMoveEthSrcToEthDstAction() {
-        return nxMoveRegAction(new SrcOfEthSrcCaseBuilder()
-                                   .setOfEthSrc(Boolean.TRUE).build(),
-                               new DstOfEthDstCaseBuilder()
-                                   .setOfEthDst(Boolean.TRUE).build(),
+        return nxMoveRegAction(new SrcOfEthSrcCaseBuilder().setOfEthSrc(Boolean.TRUE).build(),
+                               new DstOfEthDstCaseBuilder().setOfEthDst(Boolean.TRUE).build(),
                                47, false);
     }
 
     public static Action nxMoveArpSpaToArpTpaAction() {
-        return nxMoveRegAction(new SrcOfArpSpaCaseBuilder()
-                                   .setOfArpSpa(Boolean.TRUE).build(),
-                               new DstOfArpTpaCaseBuilder()
-                                   .setOfArpTpa(Boolean.TRUE).build());
+        return nxMoveRegAction(new SrcOfArpSpaCaseBuilder().setOfArpSpa(Boolean.TRUE).build(),
+                               new DstOfArpTpaCaseBuilder().setOfArpTpa(Boolean.TRUE).build());
     }
 
     public static Action nxOutputRegAction(SrcChoice srcChoice) {
@@ -359,13 +354,31 @@ public final class ActionUtils {
     }
 
     public static Action nxMoveRegTunDstToNshc1() {
-        return nxMoveRegAction(new SrcNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
-                new DstNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(), 31, false);
+        return nxMoveRegAction(
+                new SrcNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
+                new DstNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(),
+                31, false);
     }
 
     public static Action nxMoveTunIdtoNshc2() {
-        return nxMoveRegAction(new SrcNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
-                new DstNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(), 31, false);
+        return nxMoveRegAction(
+                new SrcNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
+                new DstNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(),
+                31, false);
+    }
+
+    public static Action nxMoveNshc1ToTunIpv4Dst() {
+        return nxMoveRegAction(
+                new SrcNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(),
+                new DstNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(),
+                31, false);
+    }
+
+    public static Action nxMoveNshc2ToTunId() {
+        return nxMoveRegAction(
+                new SrcNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(),
+                new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
+                31, false);
     }
 
     public static Action nxLoadTunIdAction(BigInteger tunnelId, boolean groupBucket) {
index 9d61386b8efba1be8e6610cd4e9ea1bd3630d0d3..1bfde3e21f20e8897f2354d8d9b03d8843a626ba 100644 (file)
@@ -113,7 +113,7 @@ public class InstructionUtils {
     }
 
     /**
-     * Create NORMAL Reserved Port Instruction (packet_in)
+     * Create LOCAL Reserved Port Instruction
      *
      * @param nodeName Uri Prefix, containing nodeConnectorType and dpId (aka NodeId)
      * @param ib Map InstructionBuilder without any instructions
@@ -144,6 +144,35 @@ public class InstructionUtils {
         return ib;
     }
 
+    /**
+     * Create NORMAL Reserved Port Instruction (packet_in)
+     *
+     * @param ib Map InstructionBuilder without any instructions
+     * @param dpidLong Long the datapath ID of a switch/node
+     * @return ib Map InstructionBuilder with instructions
+     */
+    public static InstructionBuilder createLocalInstructions(InstructionBuilder ib, long dpidLong) {
+        List<Action> actionList = new ArrayList<>();
+        ActionBuilder ab = new ActionBuilder();
+
+        OutputActionBuilder output = new OutputActionBuilder();
+        output.setOutputNodeConnector(new NodeConnectorId("openflow:" + dpidLong + ":"
+                + OutputPortValues.LOCAL.toString()));
+        ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
+        ab.setOrder(0);
+        ab.setKey(new ActionKey(0));
+        actionList.add(ab.build());
+
+        // Create an Apply Action
+        ApplyActionsBuilder aab = new ApplyActionsBuilder();
+        aab.setAction(actionList);
+
+        // Wrap our Apply Action in an Instruction
+        ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+        return ib;
+    }
+
     /**
      * Create Output Port Instruction
      *