<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>
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);
}
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) {
+
+ }
}
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;
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;
handleIngressClassifier(rsp, entry);
//handleEgressClassifier();
//handleSfLoopback();
+ //sfArp and ingressSfLoopback uses linux stack
}
private void handleIngressClassifier(RenderedServicePath rsp, Ace entry) {
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.
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());
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);
}
}
}
-
private RenderedServicePath getRenderedServicePath (Ace entry) {
RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
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);
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;
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;
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);
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());
}
}
- 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());
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;
}
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();
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;
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;
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) {
}
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) {
}
/**
- * 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
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
*