return Optional.of(new NodeId("openflow:" + dpnId.getValue()));
}
- public Optional<String> getIpFromInterfaceName(String interfaceName) {
- Optional<DpnIdType> dpnId = getDpnIdFromInterfaceName(interfaceName);
- if (!dpnId.isPresent()) {
- LOG.warn("getIpFromInterfaceName empty dpnId for interfaceName [{}]", interfaceName);
- return Optional.empty();
- }
-
- List<IpAddress> ipList = getIpFromDpnId(dpnId.get());
- if (ipList.isEmpty()) {
- LOG.warn("getIpFromInterfaceName empty ipList for interfaceName [{}]", interfaceName);
- return Optional.empty();
- }
-
- // TODO need to figure out why it returns a list, using first entry for now
- return Optional.ofNullable(ipList.get(0).getIpv4Address().getValue());
- }
-
// TODO Should better use the Genius InterfaceManager to avoid duplicate code
// https://bugs.opendaylight.org/show_bug.cgi?id=8127
- public List<IpAddress> getIpFromDpnId(DpnIdType dpnid) {
+ public Optional<String> getIpFromDpnId(DpnIdType dpnid) {
GetEndpointIpForDpnInputBuilder builder = new GetEndpointIpForDpnInputBuilder();
builder.setDpid(dpnid.getValue());
GetEndpointIpForDpnInput input = builder.build();
if (interfaceManagerRpcService == null) {
LOG.error("getIpFromDpnId({}) failed (service couldn't be retrieved)", input);
- return Collections.emptyList();
+ return Optional.empty();
}
try {
RpcResult<GetEndpointIpForDpnOutput> output = interfaceManagerRpcService.getEndpointIpForDpn(input).get();
if (!output.isSuccessful()) {
LOG.error("getIpFromDpnId({}) failed: {}", input, output);
- return Collections.emptyList();
+ return Optional.empty();
}
- List<IpAddress> localIps = output.getResult().getLocalIps();
LOG.debug("getDpnIdFromInterfaceName({}) succeeded: {}", input, output);
- if (localIps != null) {
- return localIps;
- }
+ List<IpAddress> localIps = output.getResult().getLocalIps();
+
+ // TODO need to figure out why it returns a list, using first entry for now
+ return Optional.ofNullable(localIps)
+ .filter(ipAddresses -> !ipAddresses.isEmpty())
+ .map(ipAddresses -> ipAddresses.get(0))
+ .map(IpAddress::getIpv4Address)
+ .map(Ipv4Address::getValue);
} catch (InterruptedException | ExecutionException e) {
LOG.error("getDpnIdFromInterfaceName failed to retrieve target interface name: ", e);
}
- return Collections.emptyList();
+ return Optional.empty();
}
public Optional<DpnIdType> getDpnIdFromInterfaceName(String interfaceName) {
public static final BigInteger EGRESS_CLASSIFIER_TPORTEGRESS_COOKIE = new BigInteger("F005BA1100000005", 16);
// Priorities for each flow
+ public static final int INGRESS_CLASSIFIER_FILTER_CHAIN_EGRESS_PRIORITY = 520;
public static final int INGRESS_CLASSIFIER_FILTER_NSH_PRIORITY = 510;
public static final int INGRESS_CLASSIFIER_FILTER_NONSH_PRIORITY = 500;
public static final int INGRESS_CLASSIFIER_ACL_PRIORITY = 500;
public static final int EGRESS_CLASSIFIER_EGRESS_REMOTE_PRIORITY = 250;
// Flow names for each table
+ public static final String INGRESS_CLASSIFIER_FILTER_NSH_CHAIN_EGRESS_FLOW_NAME =
+ "nvsfc_ingr_class_filter_chain_egress";
public static final String INGRESS_CLASSIFIER_FILTER_VXGPENSH_FLOW_NAME = "nvsfc_ingr_class_filter_vxgpe";
public static final String INGRESS_CLASSIFIER_FILTER_ETHNSH_FLOW_NAME = "nvsfc_ingr_class_filter_eth";
public static final String INGRESS_CLASSIFIER_FILTER_NONSH_FLOW_NAME = "nvsfc_ingr_class_filter_nonsh";
INGRESS_CLASSIFIER_FILTER_ETHNSH_FLOW_NAME, flowIdStr, match, isb).build();
}
+ /*
+ * Classifier chain termination flow:
+ * Handle packets at the end of the chain
+ * Match C1 on local IP, NSP and ending NSI, restore metadata and
+ * resubmit to egress dispatcher
+ */
+ public Flow createIngressClassifierFilterChainEgressFlow(NodeId nodeId, long nsp) {
+
+ MatchBuilder match = new MatchBuilder();
+ OpenFlow13Utils.addMatchNsp(match, nsp);
+
+ List<Action> actionList = new ArrayList<>();
+ actionList.add(OpenFlow13Utils.createActionNxMoveNsc4ToReg6Register(actionList.size()));
+ actionList.add(OpenFlow13Utils.createActionNxPopNsh(actionList.size()));
+ actionList.add(OpenFlow13Utils.createActionResubmitTable(NwConstants.EGRESS_LPORT_DISPATCHER_TABLE,
+ actionList.size()));
+
+ InstructionsBuilder isb = OpenFlow13Utils.wrapActionsIntoApplyActionsInstruction(actionList);
+ String flowIdStr = INGRESS_CLASSIFIER_FILTER_NSH_CHAIN_EGRESS_FLOW_NAME + nodeId.getValue() + "_" + nsp;
+
+ return OpenFlow13Utils.createFlowBuilder(NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE,
+ INGRESS_CLASSIFIER_FILTER_CHAIN_EGRESS_PRIORITY, INGRESS_CLASSIFIER_FILTER_COOKIE,
+ INGRESS_CLASSIFIER_FILTER_NSH_CHAIN_EGRESS_FLOW_NAME, flowIdStr, match, isb).build();
+ }
+
/*
* Ingress Classifier Filter No NSH flow:
* Only allows Non-NSH packets to proceed in the classifier
List<Action> actionList = new ArrayList<>();
actionList.add(OpenFlow13Utils.createActionNxMoveReg0ToNsc1Register(actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxMoveTunIdToNsc2Register(actionList.size()));
+ actionList.add(OpenFlow13Utils.createActionNxMoveReg6ToNsc4Register(actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxLoadTunId(SFC_TUNNEL_ID, actionList.size()));
InstructionsBuilder isb = OpenFlow13Utils.wrapActionsIntoApplyActionsInstruction(actionList);
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntries;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.sfc.acl.rev150105.NetvirtsfcAclActions;
private final GeniusProvider geniusProvider;
private final NetvirtProvider netvirtProvider;
private static final Logger LOG = LoggerFactory.getLogger(ConfigurationClassifierImpl.class);
+ private static final String LOCAL_HOST_IP = "127.0.0.1";
public ConfigurationClassifierImpl(GeniusProvider geniusProvider,
NetvirtProvider netvirtProvider,
return Collections.emptySet();
}
- String firstHopIp = sfcProvider.getFirstHopSfInterfaceFromRsp(rsp)
- .flatMap(geniusProvider::getIpFromInterfaceName)
+ DpnIdType firstHopDpn = sfcProvider.getFirstHopSfInterfaceFromRsp(rsp)
+ .flatMap(geniusProvider::getDpnIdFromInterfaceName)
.orElse(null);
- if (firstHopIp == null) {
- LOG.trace("Could not acquire a valid first RSP hop destination ip");
+ if (firstHopDpn == null) {
+ LOG.error("RSP has no valid first hop DPN");
return Collections.emptySet();
}
+
Map<NodeId, List<InterfaceKey>> nodeToInterfaces = new HashMap<>();
NeutronNetwork neutronNetwork = matches.getAugmentation(NeutronNetwork.class);
if (neutronNetwork != null) {
LOG.trace("Got classifier nodes and interfaces: {}", nodeToInterfaces);
+ String firstHopIp = geniusProvider.getIpFromDpnId(firstHopDpn).orElse(null);
Set<ClassifierRenderableEntry> entries = new HashSet<>();
nodeToInterfaces.forEach((nodeId, ifaces) -> {
// Get node info
- DpnIdType dpnIdType = new DpnIdType(OpenFlow13Provider.getDpnIdFromNodeId(nodeId));
- List<String> nodeIps = geniusProvider.getIpFromDpnId(dpnIdType).stream()
- .map(IpAddress::getIpv4Address)
- .filter(Objects::nonNull)
- .map(Ipv4Address::getValue)
- .collect(Collectors.toList());
- String nodeIp = nodeIps.isEmpty() ? null : nodeIps.get(0);
-
- if (nodeIp == null) {
- LOG.trace("Could not get IP address for node {}, skipping", nodeId.getValue());
+ DpnIdType nodeDpn = new DpnIdType(OpenFlow13Provider.getDpnIdFromNodeId(nodeId));
+ String nodeIp = geniusProvider.getIpFromDpnId(nodeDpn).orElse(LOCAL_HOST_IP);
+
+ if (firstHopIp == null && !nodeDpn.equals(firstHopDpn)) {
+ LOG.warn("Classifier on node {} has no IP to reach first hop on node {}", nodeDpn, firstHopDpn);
return;
}
entries.add(ClassifierEntry.buildPathEntry(
nodeId,
nsp,
- nodeIps.contains(firstHopIp) ? null : firstHopIp));
+ nodeDpn.equals(firstHopDpn) ? null : firstHopIp));
// Add entries based on ingress interface
ifaces.forEach(interfaceKey -> {
@Override
public void renderPath(NodeId nodeId, Long nsp, String firstHopIp) {
- Long port = geniusProvider.getEgressVxlanPortForNode(OpenFlow13Provider.getDpnIdFromNodeId(nodeId))
- .orElse(null);
- if (port == null) {
- LOG.error("OpenflowRenderer: cant get egressPort for nodeId [{}]", nodeId.getValue());
- return;
+ List<Flow> flows = new ArrayList<>();
+ if (firstHopIp != null) {
+ Long port = geniusProvider.getEgressVxlanPortForNode(OpenFlow13Provider.getDpnIdFromNodeId(nodeId))
+ .orElse(null);
+ if (port == null) {
+ LOG.error("OpenflowRenderer: cant get egressPort for nodeId [{}]", nodeId.getValue());
+ return;
+ }
+ Flow flow;
+ flow = openFlow13Provider.createEgressClassifierTransportEgressRemoteFlow(nodeId, nsp, port, firstHopIp);
+ flows.add(flow);
+ } else {
+ Flow flow;
+ flow = openFlow13Provider.createEgressClassifierTransportEgressLocalFlow(nodeId, nsp);
+ flows.add(flow);
}
-
- Flow flow = firstHopIp == null
- ? openFlow13Provider.createEgressClassifierTransportEgressLocalFlow(nodeId, nsp)
- : openFlow13Provider.createEgressClassifierTransportEgressRemoteFlow(nodeId, nsp, port, firstHopIp);
-
+ flows.add(openFlow13Provider.createIngressClassifierFilterChainEgressFlow(nodeId, nsp));
WriteTransaction tx = this.dataBroker.newWriteOnlyTransaction();
- this.openFlow13Provider.appendFlowForCreate(nodeId, flow, tx);
+ flows.forEach(flow -> this.openFlow13Provider.appendFlowForCreate(nodeId, flow, tx));
tx.submit();
}
@Override
public void suppressPath(NodeId nodeId, Long nsp, String firstHopIp) {
- Long port = geniusProvider.getEgressVxlanPortForNode(OpenFlow13Provider.getDpnIdFromNodeId(nodeId))
- .orElse(null);
-
- if (port == null) {
- LOG.error("OpenflowRenderer: cant get egressPort for nodeId [{}]", nodeId.getValue());
- return;
+ List<Flow> flows = new ArrayList<>();
+ if (firstHopIp != null) {
+ Long port = geniusProvider.getEgressVxlanPortForNode(OpenFlow13Provider.getDpnIdFromNodeId(nodeId))
+ .orElse(null);
+ if (port == null) {
+ LOG.error("OpenflowRenderer: cant get egressPort for nodeId [{}]", nodeId.getValue());
+ return;
+ }
+ Flow flow;
+ flow = openFlow13Provider.createEgressClassifierTransportEgressRemoteFlow(nodeId, nsp, port, firstHopIp);
+ flows.add(flow);
+ } else {
+ Flow flow;
+ flow = openFlow13Provider.createEgressClassifierTransportEgressLocalFlow(nodeId, nsp);
+ flows.add(flow);
}
-
- Flow flow = firstHopIp == null
- ? openFlow13Provider.createEgressClassifierTransportEgressLocalFlow(nodeId, nsp)
- : openFlow13Provider.createEgressClassifierTransportEgressRemoteFlow(nodeId, nsp, port, firstHopIp);
-
+ flows.add(openFlow13Provider.createIngressClassifierFilterChainEgressFlow(nodeId, nsp));
WriteTransaction tx = this.dataBroker.newWriteOnlyTransaction();
- this.openFlow13Provider.appendFlowForCreate(nodeId, flow, tx);
+ flows.forEach(flow -> this.openFlow13Provider.appendFlowForDelete(nodeId, flow, tx));
tx.submit();
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
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.GeneralAugMatchNodesNodeTableFlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshNpCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc1CaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc2CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc4CaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNsiCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNspCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIpv4DstCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPopNshNodesNodeTableFlowApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPushNshNodesNodeTableFlowApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNodesNodeTableFlowWriteActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.pop.nsh.grouping.NxPopNsh;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.pop.nsh.grouping.NxPopNshBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.push.nsh.grouping.NxPushNsh;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.push.nsh.grouping.NxPushNshBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.SrcBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmitBuilder;
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.SrcNxNshc4CaseBuilder;
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.match.rev140714.NxAugMatchNodesNodeTableFlow;
match.setInPort(new NodeConnectorId(nodeId.getValue() + ":" + inPort));
}
+ public static void addMatchNsp(MatchBuilder match, long nsp) {
+ NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder()
+ .setNxmNxNsp(new NxmNxNspBuilder().setValue(nsp).build()).build();
+ addExtension(match, NxmNxNspKey.class, am);
+ }
+
public static void addMatchNshNsc1(MatchBuilder match, long nsc) {
NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder()
.setNxmNxNshc1(new NxmNxNshc1Builder().setValue(nsc).build()).build();
return ab.build();
}
+ public static Action createActionNxPopNsh(int order) {
+ NxPopNshBuilder builder = new NxPopNshBuilder();
+ NxPopNsh nxPopNsh = builder.build();
+
+ ActionBuilder ab = createActionBuilder(order);
+ ab.setAction(new NxActionPopNshNodesNodeTableFlowApplyActionsCaseBuilder().setNxPopNsh(nxPopNsh).build());
+
+ return ab.build();
+ }
+
public static Action createActionNxMoveTunIdToNsc2Register(int order) {
ActionBuilder ab = createActionBuilder(order);
ab.setAction(nxMoveRegAction(new SrcNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(),
return ab.build();
}
+ public static Action createActionNxMoveReg6ToNsc4Register(int order) {
+ ActionBuilder ab = createActionBuilder(order);
+ ab.setAction(nxMoveRegAction(new SrcNxRegCaseBuilder().setNxReg(NxmNxReg6.class).build(),
+ new DstNxNshc4CaseBuilder().setNxNshc4Dst(Boolean.TRUE).build(), 31, false));
+
+ return ab.build();
+ }
+
+ public static Action createActionNxMoveNsc4ToReg6Register(int order) {
+ ActionBuilder ab = createActionBuilder(order);
+ ab.setAction(nxMoveRegAction(new SrcNxNshc4CaseBuilder().setNxNshc4Dst(Boolean.TRUE).build(),
+ new DstNxRegCaseBuilder().setNxReg(NxmNxReg6.class).build(), 31, false));
+
+ return ab.build();
+ }
+
public static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nxLoadRegAction(
DstChoice dstChoice, BigInteger value, int endOffset, boolean groupBucket) {
NxRegLoad regLoad = new NxRegLoadBuilder()
}
@Test
- public void getIpFromInterfaceName() {
+ public void getIpFromDpnId() {
// Test that it correctly handles the case when the ifName doesnt exist
- Optional<String> ipStr = this.geniusProvider.getIpFromInterfaceName(
- GeniusProviderTestParams.INTERFACE_NAME_NO_EXIST);
+ Optional<String> ipStr = this.geniusProvider.getIpFromDpnId(
+ new DpnIdType(GeniusProviderTestParams.DPN_ID_NO_EXIST));
assertFalse(ipStr.isPresent());
// Test that it correctly handles RPC errors
- ipStr = this.geniusProvider.getIpFromInterfaceName(
- GeniusProviderTestParams.INTERFACE_NAME_INVALID);
+ ipStr = this.geniusProvider.getIpFromDpnId(
+ new DpnIdType(GeniusProviderTestParams.DPN_ID_INVALID));
assertFalse(ipStr.isPresent());
// Test that it correctly returns the ipStr when everything is correct
- ipStr = this.geniusProvider.getIpFromInterfaceName(
- GeniusProviderTestParams.INTERFACE_NAME);
+ ipStr = this.geniusProvider.getIpFromDpnId(
+ new DpnIdType(GeniusProviderTestParams.DPN_ID));
assertTrue(ipStr.isPresent());
assertEquals(ipStr.get(), GeniusProviderTestParams.IPV4_ADDRESS_STR);
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
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.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshNpCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc1Case;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc2Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc4Case;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNsiCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNspCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIpv4DstCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPopNshNodesNodeTableFlowApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPushNshNodesNodeTableFlowApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNodesNodeTableFlowApplyActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionResubmitNodesNodeTableFlowWriteActionsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc1Case;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc2Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc4Case;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIdCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
NwConstants.LPORT_DISPATCHER_TABLE);
}
+ @Test
+ public void createIngressClassifierFilterChainEgressFlow() {
+ Flow flow = openflowProvider.createIngressClassifierFilterChainEgressFlow(nodeId, NSP);
+
+ assertEquals(flow.getTableId().shortValue(), NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE);
+ assertEquals(flow.getPriority().intValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_CHAIN_EGRESS_PRIORITY);
+ assertEquals(flow.getId().getValue(),
+ OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_NSH_CHAIN_EGRESS_FLOW_NAME
+ + nodeId.getValue() + "_" + NSP);
+ assertEquals(flow.getCookie().getValue(), OpenFlow13Provider.INGRESS_CLASSIFIER_FILTER_COOKIE);
+
+ checkMatchNsp(flow.getMatch(), NSP);
+ assertEquals(1, flow.getInstructions().getInstruction().size());
+ Instruction curInstruction = flow.getInstructions().getInstruction().get(0).getInstruction();
+ List<Action> actionList = checkApplyActionSize(curInstruction, 3);
+ checkActionMoveNsc4(actionList.get(0), true);
+ checkActionMoveTunReg(actionList.get(0), NxmNxReg6.class, false);
+ checkActionPopNsh(actionList.get(1));
+ checkActionResubmit(curInstruction, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE);
+ }
+
@Test
public void createIngressClassifierFilterNoNshFlow() {
Flow flow = openflowProvider.createIngressClassifierFilterNoNshFlow(nodeId);
assertEquals(2, flow.getInstructions().getInstruction().size());
Instruction curInstruction = flow.getInstructions().getInstruction().get(0).getInstruction();
- List<Action> actionList = checkApplyActionSize(curInstruction, 3);
+ List<Action> actionList = checkApplyActionSize(curInstruction, 4);
- checkActionMoveTunReg0(actionList.get(0), true);
+ checkActionMoveTunReg(actionList.get(0), NxmNxReg0.class, true);
checkActionMoveNsc1(actionList.get(0), false);
checkActionMoveTunId(actionList.get(1), true);
checkActionMoveNsc2(actionList.get(1), false);
- checkActionLoadTunId(actionList.get(2), OpenFlow13Provider.SFC_TUNNEL_ID);
+ checkActionMoveTunReg(actionList.get(2), NxmNxReg6.class, true);
+ checkActionMoveNsc4(actionList.get(2), false);
+ checkActionLoadTunId(actionList.get(3), OpenFlow13Provider.SFC_TUNNEL_ID);
curInstruction = flow.getInstructions().getInstruction().get(1).getInstruction();
checkActionGotoTable(curInstruction, NwConstants.EGRESS_SFC_CLASSIFIER_EGRESS_TABLE);
assertNotNull(pushNshCase.getNxPushNsh());
}
+ private void checkActionPopNsh(Action action) {
+ NxActionPopNshNodesNodeTableFlowApplyActionsCase popNshCase =
+ (NxActionPopNshNodesNodeTableFlowApplyActionsCase) action.getAction();
+ assertNotNull(popNshCase.getNxPopNsh());
+ }
+
private void checkActionLoadTunIpv4(Action action, String ip) {
long ipl = InetAddresses.coerceToInteger(InetAddresses.forString(ip)) & 0xffffffffL;
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
}
}
+ private void checkActionMoveNsc4(Action action, boolean checkSrc) {
+ NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
+ (NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
+ if (checkSrc) {
+ SrcNxNshc4Case src = (SrcNxNshc4Case) regMove.getNxRegMove().getSrc().getSrcChoice();
+ assertTrue(src.isNxNshc4Dst());
+ } else {
+ DstNxNshc4Case dst = (DstNxNshc4Case) regMove.getNxRegMove().getDst().getDstChoice();
+ assertTrue(dst.isNxNshc4Dst());
+ }
+ }
+
private void checkActionMoveTunId(Action action, boolean checkSrc) {
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
}
}
- private void checkActionMoveTunReg0(Action action, boolean checkSrc) {
+ private void checkActionMoveTunReg(Action action, Class<? extends NxmNxReg> reg, boolean checkSrc) {
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getAction();
if (checkSrc) {
SrcNxRegCase src = (SrcNxRegCase) regMove.getNxRegMove().getSrc().getSrcChoice();
- assertTrue(src.getNxReg() == NxmNxReg0.class);
+ assertTrue(src.getNxReg() == reg);
} else {
DstNxRegCase dst = (DstNxRegCase) regMove.getNxRegMove().getDst().getDstChoice();
- assertTrue(dst.getNxReg() == NxmNxReg0.class);
+ assertTrue(dst.getNxReg() == reg);
}
}
+
}