/*
* Copyright (c) 2014, 2017 Ericsson 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,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.sfc.ofrenderer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import com.google.common.net.InetAddresses;
import java.util.List;
import org.junit.Test;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.sfc.ofrenderer.openflow.SfcOfFlowProgrammerImpl;
import org.opendaylight.sfc.util.macchaining.VirtualMacAddress;
import org.opendaylight.sfc.util.openflow.OpenflowConstants;
import org.opendaylight.sfc.util.openflow.SfcOpenflowUtils;
import org.opendaylight.sfc.util.openflow.writer.SfcOfFlowWriterInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
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.flow.types.rev131026.instruction.instruction.WriteMetadataCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpShaCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpThaCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxEncapEthDstCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxEncapEthSrcCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshMdtypeCase;
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.DstNxNshc3Case;
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.DstNxTunGpeNpCase;
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.dst.choice.grouping.dst.choice.DstOfArpSpaCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpTpaCase;
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.match.rev140714.NxAugMatchNodesNodeTableFlow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* SFC OpenFlow Programmer Test.
*
* @author Ricardo Noriega (ricardo.noriega.de.soto@ericsson.com)
* @since 2015-11-25
*/
public class SfcOfFlowProgrammerTest {
private static final Logger LOG = LoggerFactory.getLogger(SfcOfFlowProgrammerTest.class);
private static final String SFF_NAME = "sff1";
private static final String MAC_SRC = "AA:BB:CC:DD:EE:FF";
private static final String MAC_DST = "FF:EE:DD:CC:BB:AA";
private static final String IP_SRC = "192.168.0.5";
private static final String IP_DST = "192.168.0.1";
private static final String INPORT = "INPORT";
private static final String PORT = "1";
private static final long PATH_ID = 123456;
private static final long PATH_ID_SMALL = 63;
private static final long SFP = 987654;
private static final long MPLS_LABEL = 1234567;
private static final boolean IS_SF = false;
private static final long NSP = 1;
private static final short NSI = 255;
private static final int VLAN_ID = 100;
private static final long GROUP_ID = 1;
private static final String GROUP_NAME = "GROUP";
private static final boolean PKTIN = false;
private static final short TABLE_BASE = 30;
private static final short TABLE_EGRESS = 80;
private SfcOfFlowWriterInterface sfcOfFlowWriter;
private SfcOfFlowProgrammerImpl sfcOfFlowProgrammer;
private FlowBuilder flowBuilder;
public SfcOfFlowProgrammerTest() {
this.flowBuilder = null;
this.sfcOfFlowWriter = mock(SfcOfFlowWriterInterface.class);
// Configure Mockito to store the FlowBuilder when writeFlowToConfig()
// is called
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
flowBuilder = (FlowBuilder) args[2];
return null;
}).when(this.sfcOfFlowWriter).writeFlow(anyLong(), anyString(), (FlowBuilder) anyObject());
// Configure Mockito to return the FlowBuilder stored by
// writeFlowToConfig()
// when getFlowBuilder() is called
// The following didnt work, since it used the value of flowBuilder at
// the time of invocation:
// when(sfcOfFlowWriter.getFlowBuilder).thenReturn(flowBuilder)
doAnswer(invocation -> flowBuilder).when(this.sfcOfFlowWriter).getFlowBuilder();
this.sfcOfFlowProgrammer = new SfcOfFlowProgrammerImpl(sfcOfFlowWriter);
}
/**
* Unit test to check match and action fields.
*
*/
@Test
public void configureIpv4TransportIngressFlow() {
sfcOfFlowProgrammer.configureIpv4TransportIngressFlow(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_INGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_INGRESS);
// TODO Two test cases for TCP/UDP shall be done
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetType().getType().getValue().longValue(),
SfcOpenflowUtils.ETHERTYPE_IPV4);
LOG.info("configureIpv4TransportIngressFlow() Match EtherType: [{}]",
match.getEthernetMatch().getEthernetType().getType().getValue());
// Now check that the actions are: Goto Table TABLE_INDEX_PATH_MAPPER
Instructions isb = flowBuilder.getInstructions();
Instruction curInstruction = isb.getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
LOG.info("configureIpv4TransportIngressFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureVlanTransportIngressFlow() {
sfcOfFlowProgrammer.configureVlanTransportIngressFlow(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_INGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_INGRESS);
Match match = flowBuilder.getMatch();
assertTrue(match.getVlanMatch().getVlanId().isVlanIdPresent());
LOG.info("configureVlanTransportIngressFlow() VLAN Match : [{}]",
match.getVlanMatch().getVlanId().isVlanIdPresent());
Instructions isb = flowBuilder.getInstructions();
Instruction curInstruction = isb.getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
LOG.info("configureVlanTransportIngressFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNshVxgpeTransportIngressFlow() {
sfcOfFlowProgrammer.configureNshVxgpeTransportIngressFlow(SFF_NAME, NSP, NSI);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_INGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_INGRESS);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
Instructions isb = flowBuilder.getInstructions();
Instruction curInstruction = isb.getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
LOG.info("configureNshVxgpeTransportIngressFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureMplsTransportIngressFlow() {
sfcOfFlowProgrammer.configureMplsTransportIngressFlow(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_INGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_INGRESS);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetType().getType().getValue().longValue(),
SfcOpenflowUtils.ETHERTYPE_MPLS_UCAST);
LOG.info("configureMplsTransportIngressFlow() Match EtherType: [{}]",
match.getEthernetMatch().getEthernetType().getType().getValue());
// TODO Two test cases for MPLS UCAST/MCAST shall be done
Instructions isb = flowBuilder.getInstructions();
Instruction curInstruction = isb.getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
LOG.info("configureMplsTransportIngressFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureArpTransportIngressFlow() {
sfcOfFlowProgrammer.configureArpTransportIngressFlow(SFF_NAME, MAC_SRC);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_INGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_ARP_TRANSPORT_INGRESS);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetType().getType().getValue().longValue(),
SfcOpenflowUtils.ETHERTYPE_ARP);
LOG.info("configureArpTransportIngressFlow() Match EtherType: [{}]",
match.getEthernetMatch().getEthernetType().getType().getValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(0)
.getAction();
SetFieldCase setField = (SetFieldCase) action.getApplyActions().getAction().get(1).getAction();
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(2)
.getAction();
assertTrue(regMove.getNxRegMove().getDst().getDstChoice() != null);
assertEquals(setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
MAC_SRC);
assertEquals(regLoad.getNxRegLoad().getValue().intValue(), SfcOpenflowUtils.ARP_REPLY);
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad2 =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(3)
.getAction();
DstNxArpShaCase arpSha = (DstNxArpShaCase) regLoad2.getNxRegLoad().getDst().getDstChoice();
assertTrue(arpSha.isNxArpSha());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove2 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(4)
.getAction();
DstNxArpThaCase arpTha = (DstNxArpThaCase) regMove2.getNxRegMove().getDst().getDstChoice();
assertTrue(arpTha.isNxArpTha());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove3 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(5)
.getAction();
DstNxRegCase regCase = (DstNxRegCase) regMove3.getNxRegMove().getDst().getDstChoice();
assertEquals(regCase.getNxReg().getCanonicalName(),
"org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0");
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove4 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(6)
.getAction();
DstOfArpTpaCase arpTpa = (DstOfArpTpaCase) regMove4.getNxRegMove().getDst().getDstChoice();
assertTrue(arpTpa.isOfArpTpa());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove5 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(7)
.getAction();
DstOfArpSpaCase arpSpa = (DstOfArpSpaCase) regMove5.getNxRegMove().getDst().getDstChoice();
assertTrue(arpSpa.isOfArpSpa());
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(8).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), INPORT);
LOG.info("configureArpTransportIngressFlow() Action ArpOp: [{}], SrcMac: [{}], Output port: [{}]",
regLoad.getNxRegLoad().getValue().intValue(),
setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureMplsPathMapperFlow() {
sfcOfFlowProgrammer.configureMplsPathMapperFlow(SFF_NAME, MPLS_LABEL, PATH_ID, IS_SF);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_PATH_MAPPER);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetType().getType().getValue().longValue(),
SfcOpenflowUtils.ETHERTYPE_MPLS_UCAST);
assertEquals(match.getProtocolMatchFields().getMplsLabel().longValue(), MPLS_LABEL);
LOG.info("configureMplsPathMapperFlow() Match EtherType: [{}], Mpls Label: [{}]",
match.getEthernetMatch().getEthernetType().getType().getValue(),
match.getProtocolMatchFields().getMplsLabel());
// TODO Two test cases for MPLS UCAST/MCAST shall be done
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
checkMetadata(curInstruction, PATH_ID);
LOG.info("configureMplsPathMapperFlow() Action Metadata PathId: [{}]", PATH_ID);
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
PopMplsActionCase popMpls = (PopMplsActionCase) action.getApplyActions().getAction().get(0).getAction();
assertTrue(popMpls.getPopMplsAction() != null);
LOG.info("configureMplsPathMapperFlow() Action popMpls: [{}]", popMpls.getPopMplsAction().toString());
}
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
LOG.info("configureMplsPathMapperFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureVlanPathMapperFlow() {
sfcOfFlowProgrammer.configureVlanPathMapperFlow(SFF_NAME, VLAN_ID, PATH_ID, IS_SF);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_PATH_MAPPER);
Match match = flowBuilder.getMatch();
assertEquals(match.getVlanMatch().getVlanId().getVlanId().getValue().intValue(), VLAN_ID);
LOG.info("configureVlanPathMapperFlow() Match VlanId: [{}]",
match.getVlanMatch().getVlanId().getVlanId().getValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
checkMetadata(curInstruction, PATH_ID);
LOG.info("configureVlanPathMapperFlow() Action Metadata PathId: [{}]", PATH_ID);
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
PopVlanActionCase popVlan = (PopVlanActionCase) action.getApplyActions().getAction().get(0).getAction();
assertTrue(popVlan.getPopVlanAction() != null);
LOG.info("configureVlanPathMapperFlow() Action PopVlan: [{}]", popVlan.getPopVlanAction().toString());
}
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
LOG.info("configureVlanPathMapperFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureMacNextHopFlow() {
sfcOfFlowProgrammer.configureMacNextHopFlow(SFF_NAME, SFP, MAC_SRC, MAC_DST);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_NEXT_HOP);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetSource().getAddress().getValue(), MAC_SRC);
assertEquals(match.getMetadata().getMetadata().longValue(), SFP);
LOG.info("configureNextHopFlow() Match SrcMac: [{}], Sfp: [{}]",
match.getEthernetMatch().getEthernetSource().getAddress().getValue(),
match.getMetadata().getMetadata().longValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
SetFieldCase setField = (SetFieldCase) action.getApplyActions().getAction().get(0).getAction();
assertEquals(setField.getSetField().getEthernetMatch().getEthernetDestination().getAddress().getValue(),
MAC_DST);
LOG.info("configureNextHopFlow() Action Set DstMac: [{}]",
setField.getSetField().getEthernetMatch().getEthernetDestination().getAddress().getValue());
}
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
LOG.info("configureNextHopFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
}
}
/**
* Unit test to check match and action fields from mac chaining flows of no transparent SFs.
*
*/
@Test
public void configureMacChainingNoTransparentSfsNextHopFlow() {
VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(PATH_ID, 0);
String vmac = hopMac.getHop(NSI).getValue();
String nextVmac = hopMac.getHop((short)(NSI - 1)).getValue();
sfcOfFlowProgrammer.configureMacChainingNextHopFlow(SFF_NAME, vmac, MAC_DST, nextVmac, false);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_NEXT_HOP);
Match match = flowBuilder.getMatch();
// transparent equals false -> VMAC should be match in the destination MAC address
assertEquals(match.getEthernetMatch().getEthernetDestination().getAddress().getValue(), vmac);
LOG.info("configureMacChainingNextHopFlow() Match DstMac: [{}]",
match.getEthernetMatch().getEthernetDestination().getAddress().getValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
SetFieldCase setField1 = (SetFieldCase) action.getApplyActions().getAction().get(0).getAction();
assertEquals(setField1.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
nextVmac);
LOG.info("configureNextHopFlow() Action Set SrcMac: [{}]",
setField1.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue());
SetFieldCase setField2 = (SetFieldCase) action.getApplyActions().getAction().get(1).getAction();
assertEquals(setField2.getSetField().getEthernetMatch()
.getEthernetDestination().getAddress().getValue(), MAC_DST);
LOG.info("configureNextHopFlow() Action Set DstMac: [{}]",
setField2.getSetField().getEthernetMatch().getEthernetDestination().getAddress().getValue());
}
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
LOG.info("configureNextHopFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
}
}
/**
* Unit test to check match and action fields from mac chaining flows of transparent SFs.
*
*/
@Test
public void configureMacChainingTransparentSfsNextHopFlow() {
VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(PATH_ID, 0);
String vmac = hopMac.getHop(NSI).getValue();
String nextVmac = hopMac.getHop((short)(NSI - 1)).getValue();
sfcOfFlowProgrammer.configureMacChainingNextHopFlow(SFF_NAME, vmac, MAC_DST, nextVmac, true);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_NEXT_HOP);
Match match = flowBuilder.getMatch();
// transparent equals true -> VMAC should be match in the source MAC address
assertEquals(match.getEthernetMatch().getEthernetSource().getAddress().getValue(), vmac);
LOG.info("configureMacChainingNextHopFlow() Match DstMac: [{}]",
match.getEthernetMatch().getEthernetSource().getAddress().getValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
SetFieldCase setField1 = (SetFieldCase) action.getApplyActions().getAction().get(0).getAction();
assertEquals(setField1.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
nextVmac);
LOG.info("configureNextHopFlow() Action Set SrcMac: [{}]",
setField1.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue());
SetFieldCase setField2 = (SetFieldCase) action.getApplyActions().getAction().get(1).getAction();
assertEquals(setField2.getSetField().getEthernetMatch()
.getEthernetDestination().getAddress().getValue(), MAC_DST);
LOG.info("configureNextHopFlow() Action Set DstMac: [{}]",
setField2.getSetField().getEthernetMatch().getEthernetDestination().getAddress().getValue());
}
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
LOG.info("configureNextHopFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureGroupNextHopFlow() {
sfcOfFlowProgrammer.configureGroupNextHopFlow(SFF_NAME, SFP, MAC_SRC, GROUP_ID, GROUP_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_NEXT_HOP);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetSource().getAddress().getValue(), MAC_SRC);
assertEquals(match.getMetadata().getMetadata().longValue(), SFP);
LOG.info("configureGroupNextHopFlow() Match SrcMac: [{}], Sfp: [{}]",
match.getEthernetMatch().getEthernetSource().getAddress().getValue(),
match.getMetadata().getMetadata().longValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
GroupActionCase group = (GroupActionCase) action.getApplyActions().getAction().get(0).getAction();
assertEquals(group.getGroupAction().getGroup(), GROUP_NAME);
assertEquals(group.getGroupAction().getGroupId().longValue(), GROUP_ID);
LOG.info("configureGroupNextHopFlow() Action GroupName: [{}], GroupId: [{}]",
group.getGroupAction().getGroup(), group.getGroupAction().getGroupId());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNshVxgpeNextHopFlow() {
sfcOfFlowProgrammer.configureNshVxgpeNextHopFlow(SFF_NAME, IP_DST, null, NSP, NSI);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_NEXT_HOP);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
NxActionRegLoadNodesNodeTableFlowApplyActionsCase nxLoad =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(0)
.getAction();
int ip = InetAddresses.coerceToInteger(InetAddresses.forString(IP_DST));
long ipl = ip & 0xffffffffL;
assertEquals(nxLoad.getNxRegLoad().getValue().longValue(), ipl);
LOG.info("configureNshVxgpeNextHopFlow() Action DstTunIP long: [{}]",
nxLoad.getNxRegLoad().getValue().longValue());
}
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
LOG.info("configureNshVxgpeNextHopFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNshEthNextHopFlow() {
sfcOfFlowProgrammer.configureNshEthNextHopFlow(SFF_NAME, MAC_SRC, MAC_DST, NSP, NSI);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_NEXT_HOP);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad0 =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(0)
.getAction();
DstNxEncapEthSrcCase encapEthSrc =
(DstNxEncapEthSrcCase) regLoad0.getNxRegLoad().getDst().getDstChoice();
assertTrue(encapEthSrc.isNxEncapEthSrc());
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad1 =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(1)
.getAction();
DstNxEncapEthDstCase encapEthDst =
(DstNxEncapEthDstCase) regLoad1.getNxRegLoad().getDst().getDstChoice();
assertTrue(encapEthDst.isNxEncapEthDst());
LOG.info("configureNshVxgpeNextHopFlow() Action: [{}]", action);
}
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
LOG.info("configureNshEthNextHopFlow() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureVlanSfTransportEgressFlow() {
sfcOfFlowProgrammer.configureVlanSfTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, VLAN_ID, PORT, PATH_ID_SMALL,
PKTIN);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS + 10);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetDestination().getAddress().getValue(), MAC_DST);
assertEquals(match.getMetadata().getMetadata().longValue(), PATH_ID_SMALL);
LOG.info("configureMacTransportEgressFlow() Match DstMac: [{}], Sfp: [{}]",
match.getEthernetMatch().getEthernetDestination().getAddress().getValue(),
match.getMetadata().getMetadata().longValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
SetFieldCase dscp = (SetFieldCase) action.getApplyActions().getAction().get(0).getAction();
PushVlanActionCase pushVlan =
(PushVlanActionCase) action.getApplyActions().getAction().get(1).getAction();
SetFieldCase vlanId = (SetFieldCase) action.getApplyActions().getAction().get(2).getAction();
assertEquals(dscp.getSetField().getIpMatch().getIpDscp().getValue().shortValue(), PATH_ID_SMALL);
assertEquals(pushVlan.getPushVlanAction().getEthernetType().intValue(),
SfcOpenflowUtils.ETHERTYPE_VLAN);
assertEquals(vlanId.getSetField().getVlanMatch().getVlanId().getVlanId().getValue().intValue(),
VLAN_ID);
SetFieldCase setField = (SetFieldCase) action.getApplyActions().getAction().get(3).getAction();
assertEquals(setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
MAC_SRC);
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(4).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), PORT);
LOG.info("configureMacTransportEgressFlow() Action SrcMac: [{}], OutputPort: [{}]",
setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows to forward packet to other SFFs.
*
*/
@Test
public void configureMacChainingSffTransportEgressFlow() {
VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(PATH_ID, 0);
String vmac = hopMac.getHop(NSI).getValue();
sfcOfFlowProgrammer.configureMacChainingSfTransportEgressFlow(SFF_NAME, MAC_DST, PORT, vmac);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetDestination().getAddress().getValue(), MAC_DST);
LOG.info("configureMacTransportEgressFlow() Match DstMac: [{}]",
match.getEthernetMatch().getEthernetDestination().getAddress().getValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
SetFieldCase setField = (SetFieldCase) action.getApplyActions().getAction().get(0).getAction();
assertEquals(setField.getSetField().getEthernetMatch().getEthernetDestination().getAddress().getValue(),
vmac);
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(1).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), PORT);
LOG.info("configureMacTransportEgressFlow() Action DstMac: [{}], OutputPort: [{}]",
setField.getSetField().getEthernetMatch().getEthernetDestination().getAddress().getValue(),
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows to forward packet to SFs.
*
*/
@Test
public void configureMacChainingSfTransportEgressFlow() {
sfcOfFlowProgrammer.configureMacChainingSfTransportEgressFlow(SFF_NAME, MAC_DST, PORT, null);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetDestination().getAddress().getValue(), MAC_DST);
LOG.info("configureMacTransportEgressFlow() Match DstMac: [{}]",
match.getEthernetMatch().getEthernetDestination().getAddress().getValue());
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(0).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), PORT);
LOG.info("configureMacTransportEgressFlow() Action OutputPort: [{}]",
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureVlanTransportEgressFlow() {
sfcOfFlowProgrammer.configureVlanTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, VLAN_ID, PORT, PATH_ID);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS + 10);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetDestination().getAddress().getValue(), MAC_DST);
assertEquals(match.getMetadata().getMetadata().longValue(), PATH_ID);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
PushVlanActionCase pushVlan =
(PushVlanActionCase) action.getApplyActions().getAction().get(0).getAction();
SetFieldCase vlanId = (SetFieldCase) action.getApplyActions().getAction().get(1).getAction();
SetFieldCase setField = (SetFieldCase) action.getApplyActions().getAction().get(2).getAction();
assertEquals(setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
MAC_SRC);
assertEquals(pushVlan.getPushVlanAction().getEthernetType().intValue(),
SfcOpenflowUtils.ETHERTYPE_VLAN);
assertEquals(vlanId.getSetField().getVlanMatch().getVlanId().getVlanId().getValue().intValue(),
VLAN_ID);
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(3).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), PORT);
LOG.info("Action SrcMac is: [{}], PushVlan Ethertype: [{}], VlanId: [{}], OuputPort: [{}]",
setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
pushVlan.getPushVlanAction().getEthernetType().toString(),
vlanId.getSetField().getVlanMatch().getVlanId().getVlanId().getValue(),
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNshEthTransportEgressFlow() {
sfcOfFlowProgrammer.configureNshEthTransportEgressFlow(SFF_NAME, NSP, NSI, PORT);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove0 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(0)
.getAction();
DstNxNshc1Case nshC1dst = (DstNxNshc1Case) regMove0.getNxRegMove().getDst().getDstChoice();
assertTrue(nshC1dst.isNxNshc1Dst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove1 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(1)
.getAction();
DstNxNshc2Case nshC2dst = (DstNxNshc2Case) regMove1.getNxRegMove().getDst().getDstChoice();
assertTrue(nshC2dst.isNxNshc2Dst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove2 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(2)
.getAction();
DstNxNsiCase nsiDst = (DstNxNsiCase) regMove2.getNxRegMove().getDst().getDstChoice();
assertTrue(nsiDst.isNxNsiDst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove3 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(3)
.getAction();
DstNxNspCase nspDst = (DstNxNspCase) regMove3.getNxRegMove().getDst().getDstChoice();
assertTrue(nspDst.isNxNspDst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove4 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(4)
.getAction();
DstNxNshMdtypeCase mdType = (DstNxNshMdtypeCase) regMove4.getNxRegMove().getDst().getDstChoice();
assertTrue(mdType.isNxNshMdtype());
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(5)
.getAction();
DstNxNshNpCase nshNp = (DstNxNshNpCase) regLoad.getNxRegLoad().getDst().getDstChoice();
assertTrue(nshNp.isNxNshNp());
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(6).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), PORT);
LOG.info("configureNshEthTransportEgressFlow() Action OutputPort: [{}]",
output.getOutputAction().getOutputNodeConnector());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNshVxgpeTransportEgressFlow() {
sfcOfFlowProgrammer.configureNshVxgpeTransportEgressFlow(SFF_NAME, NSP, NSI, PORT);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
int priority = flowBuilder.getPriority();
assertTrue(priority == SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS
|| priority == SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS + 5);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove0 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(0)
.getAction();
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove1 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(1)
.getAction();
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove2 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(2)
.getAction();
DstNxNshMdtypeCase mdType = (DstNxNshMdtypeCase) regMove0.getNxRegMove().getDst().getDstChoice();
DstNxNshNpCase nshNp = (DstNxNshNpCase) regMove1.getNxRegMove().getDst().getDstChoice();
DstNxNshc1Case nshC1dst = (DstNxNshc1Case) regMove2.getNxRegMove().getDst().getDstChoice();
assertTrue(mdType.isNxNshMdtype());
assertTrue(nshNp.isNxNshNp());
assertTrue(nshC1dst.isNxNshc1Dst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove3 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(3)
.getAction();
DstNxNshc2Case nshC2dst = (DstNxNshc2Case) regMove3.getNxRegMove().getDst().getDstChoice();
assertTrue(nshC2dst.isNxNshc2Dst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove4 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(4)
.getAction();
DstNxNshc3Case nshC3dst = (DstNxNshc3Case) regMove4.getNxRegMove().getDst().getDstChoice();
assertTrue(nshC3dst.isNxNshc3Dst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove5 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(5)
.getAction();
DstNxNshc4Case nshC4dst = (DstNxNshc4Case) regMove5.getNxRegMove().getDst().getDstChoice();
assertTrue(nshC4dst.isNxNshc4Dst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove6 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(6)
.getAction();
DstNxTunIdCase tunIdDst = (DstNxTunIdCase) regMove6.getNxRegMove().getDst().getDstChoice();
assertTrue(tunIdDst.isNxTunId());
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(7)
.getAction();
DstNxTunGpeNpCase gpeNp = (DstNxTunGpeNpCase) regLoad.getNxRegLoad().getDst().getDstChoice();
assertTrue(gpeNp.isNxTunGpeNp());
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(8).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), INPORT);
LOG.info("configureNshVxgpeTransportEgressFlow() Action OutputPort: [{}]",
output.getOutputAction().getOutputNodeConnector());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNshVxgpeLastHopTransportEgressFlow() {
sfcOfFlowProgrammer.configureNshVxgpeLastHopTransportEgressFlow(SFF_NAME, NSP, NSI, PORT);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS + 5);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove0 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(0)
.getAction();
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove1 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(1)
.getAction();
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove2 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(2)
.getAction();
DstNxNshMdtypeCase mdType = (DstNxNshMdtypeCase) regMove0.getNxRegMove().getDst().getDstChoice();
DstNxNshNpCase nshNp = (DstNxNshNpCase) regMove1.getNxRegMove().getDst().getDstChoice();
DstNxNsiCase nshNsi = (DstNxNsiCase) regMove2.getNxRegMove().getDst().getDstChoice();
assertTrue(mdType.isNxNshMdtype());
assertTrue(nshNp.isNxNshNp());
assertTrue(nshNsi.isNxNsiDst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove3 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(3)
.getAction();
DstNxNspCase nshNsp = (DstNxNspCase) regMove3.getNxRegMove().getDst().getDstChoice();
assertTrue(nshNsp.isNxNspDst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove4 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(4)
.getAction();
DstNxTunIpv4DstCase tunIpv4Dst = (DstNxTunIpv4DstCase) regMove4.getNxRegMove().getDst().getDstChoice();
assertTrue(tunIpv4Dst.isNxTunIpv4Dst());
NxActionRegMoveNodesNodeTableFlowApplyActionsCase regMove5 =
(NxActionRegMoveNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(5)
.getAction();
DstNxTunIdCase tunIdDst = (DstNxTunIdCase) regMove5.getNxRegMove().getDst().getDstChoice();
assertTrue(tunIdDst.isNxTunId());
NxActionRegLoadNodesNodeTableFlowApplyActionsCase regLoad =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(6)
.getAction();
DstNxTunGpeNpCase gpeNp = (DstNxTunGpeNpCase) regLoad.getNxRegLoad().getDst().getDstChoice();
assertTrue(gpeNp.isNxTunGpeNp());
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(7).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), INPORT);
LOG.info("configureNshVxgpeTransportEgressFlow() Action OutputPort: [{}]",
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureMplsTransportEgressFlow() {
sfcOfFlowProgrammer.configureMplsTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, MPLS_LABEL, PORT, PATH_ID);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS + 10);
Match match = flowBuilder.getMatch();
assertEquals(match.getEthernetMatch().getEthernetDestination().getAddress().getValue(), MAC_DST);
assertEquals(match.getMetadata().getMetadata().longValue(), PATH_ID);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
PushMplsActionCase pushMpls =
(PushMplsActionCase) action.getApplyActions().getAction().get(0).getAction();
SetFieldCase mplsLabel = (SetFieldCase) action.getApplyActions().getAction().get(1).getAction();
SetFieldCase setField = (SetFieldCase) action.getApplyActions().getAction().get(2).getAction();
assertEquals(setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
MAC_SRC);
assertEquals(pushMpls.getPushMplsAction().getEthernetType().intValue(),
SfcOpenflowUtils.ETHERTYPE_MPLS_UCAST);
assertEquals(mplsLabel.getSetField().getProtocolMatchFields().getMplsLabel().longValue(), MPLS_LABEL);
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(3).getAction();
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), PORT);
LOG.info("Action SrcMac: [{}], PushMplsEthertype: [{}], LabelId: [{}], OutputPort: [{}]",
setField.getSetField().getEthernetMatch().getEthernetSource().getAddress().getValue(),
pushMpls.getPushMplsAction().getEthernetType().toString(),
mplsLabel.getSetField().getProtocolMatchFields().getMplsLabel(),
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNshNscTransportEgressFlow() {
sfcOfFlowProgrammer.configureNshNscTransportEgressFlow(SFF_NAME, NSP, NSI, PORT);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_TRANSPORT_EGRESS + 10);
checkMatchNsh(flowBuilder.build(), NSP, NSI);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
assertEquals(2, action.getApplyActions().getAction().size());
NxActionRegLoadNodesNodeTableFlowApplyActionsCase loadNextProtocol =
(NxActionRegLoadNodesNodeTableFlowApplyActionsCase) action.getApplyActions().getAction().get(0)
.getAction();
OutputActionCase output = (OutputActionCase) action.getApplyActions().getAction().get(1).getAction();
assertEquals(Short.toString(OpenflowConstants.TUN_GPE_NP_NSH),
loadNextProtocol.getNxRegLoad().getValue().toString());
assertEquals(output.getOutputAction().getOutputNodeConnector().getValue(), PORT);
LOG.info("configureNshNscTransportEgressFlow() Action OutputPort is: [{}]",
output.getOutputAction().getOutputNodeConnector().getValue());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureTransportIngressTableMatchAny() {
sfcOfFlowProgrammer.configureTransportIngressTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_INGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_MATCH_ANY);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
DropActionCase drop = (DropActionCase) action.getApplyActions().getAction().get(0).getAction();
assertTrue(drop.getDropAction() != null);
LOG.info("configureTransportIngressTableMatchAny() Action is: [{}]", drop.getDropAction().toString());
}
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureTransportIngressTableMatchAnyResubmit() {
sfcOfFlowProgrammer.configureTransportIngressTableMatchAnyResubmit(SFF_NAME,
NwConstants.LPORT_DISPATCHER_TABLE);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_INGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_MATCH_ANY);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
checkActionHasResubmit(curInstruction, NwConstants.LPORT_DISPATCHER_TABLE);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configurePathMapperTableMatchAny() {
sfcOfFlowProgrammer.configurePathMapperTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_MATCH_ANY);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER_ACL);
LOG.info("configurePathMapperTableMatchAny() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER_ACL);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configurePathMapperAclTableMatchAny() {
sfcOfFlowProgrammer.configurePathMapperAclTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER_ACL);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_MATCH_ANY);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
LOG.info("configurePathMapperAclTableMatchAny() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureNextHopTableMatchAny() {
sfcOfFlowProgrammer.configureNextHopTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_MATCH_ANY);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
checkGoToTable(curInstruction, SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
LOG.info("configureNextHopTableMatchAny() Action NextTableId: [{}]",
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
}
}
/**
* Unit test to check match and action fields from flows.
*
*/
@Test
public void configureTransportEgressTableMatchAny() {
sfcOfFlowProgrammer.configureTransportEgressTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS);
assertEquals(flowBuilder.getPriority().intValue(), SfcOfFlowProgrammerImpl.FLOW_PRIORITY_MATCH_ANY);
Instructions isb = flowBuilder.getInstructions();
for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction
instruction : isb.getInstruction()) {
Instruction curInstruction = instruction.getInstruction();
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
DropActionCase drop = (DropActionCase) action.getApplyActions().getAction().get(0).getAction();
assertTrue(drop.getDropAction() != null);
LOG.info("configureTransportEgressTableMatchAny() Action is: [{}]", drop.getDropAction().toString());
}
}
}
/**
* Unit test to check application coexistence works for NSH flows.
*/
@Test
public void appCoexistenceNsh() {
sfcOfFlowProgrammer.setTableBase(TABLE_BASE);
sfcOfFlowProgrammer.setTableEgress(TABLE_EGRESS);
// When checking the table offsets, we need to subtract 2 to compensate
// for:
// - TABLE_INDEX_CLASSIFIER=0 - which is not used for AppCoexistence
// - TABLE_INDEX_TRANSPORT_INGRESS=1 - which is table 0 for
// AppCoexistence
// Example: tableBase=20, TABLE_INDEX_PATH_MAPPER=2, should return 20
// Check that configureNshVxgpeTransportIngressFlow() is written to the
// correct table
// Notice: TransportIngress doesn't use the offset, as it will always be
// table 0
sfcOfFlowProgrammer.configureNshVxgpeTransportIngressFlow(SFF_NAME, NSP, NSI);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), 0);
// Check that configureNshVxgpeNextHopFlow() is written to the correct
// table
sfcOfFlowProgrammer.configureNshVxgpeNextHopFlow(SFF_NAME, IP_DST, null, NSP, NSI);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2);
Instruction curInstruction = flowBuilder.getInstructions().getInstruction().get(1).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2),
true);
// Check that configureNshVxgpeLastHopTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureNshVxgpeLastHopTransportEgressFlow(SFF_NAME, NSP, NSI, PORT);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// Check that configureNshVxgpeTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureNshVxgpeTransportEgressFlow(SFF_NAME, NSP, NSI, PORT);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// Check that configureNshNscTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureNshNscTransportEgressFlow(SFF_NAME, NSP, NSI, PORT);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// Check that configureNshVxgpeAppCoexistTransportEgressFlow() is
// written
// to the correct table and that it goes to TABLE_EGRESS
sfcOfFlowProgrammer.configureNshVxgpeAppCoexistTransportEgressFlow(SFF_NAME, NSP, NSI, IP_SRC);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
checkActionHasResubmit(curInstruction, TABLE_EGRESS);
}
/**
* Unit test to check application coexistence works for VLAN flows.
*/
@Test
public void appCoexistenceVlan() {
sfcOfFlowProgrammer.setTableBase(TABLE_BASE);
sfcOfFlowProgrammer.setTableEgress(TABLE_EGRESS);
// When checking the table offsets, we need to subtract 2 to compensate
// for:
// - TABLE_INDEX_CLASSIFIER=0 - which is not used for AppCoexistence
// - TABLE_INDEX_TRANSPORT_INGRESS=1 - which is table 0 for
// AppCoexistence
// Example: tableBase=20, TABLE_INDEX_PATH_MAPPER=2, should return 20
// Check that configureVlanTransportIngressFlow() is written to the
// correct table
// Notice: TransportIngress doesn't use the offset, as it will always be
// table 0
sfcOfFlowProgrammer.configureVlanTransportIngressFlow(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), 0);
// Check that configureVlanPathMapperFlow() is written to the correct
// table
sfcOfFlowProgrammer.configureVlanPathMapperFlow(SFF_NAME, VLAN_ID, PATH_ID_SMALL, true);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER + TABLE_BASE - 2);
Instruction curInstruction = flowBuilder.getInstructions().getInstruction().get(2).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2), true);
// Check that configureVlanPathMapperFlow() is written to the correct
// table
sfcOfFlowProgrammer.configureVlanPathMapperFlow(SFF_NAME, VLAN_ID, PATH_ID, false);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER + TABLE_BASE - 2);
curInstruction = flowBuilder.getInstructions().getInstruction().get(2).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2), true);
// Check that configureMacNextHopFlow() is written to the correct table
sfcOfFlowProgrammer.configureMacNextHopFlow(SFF_NAME, SFP, MAC_SRC, MAC_DST);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2);
curInstruction = flowBuilder.getInstructions().getInstruction().get(1).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2),
true);
// Check that configureVlanSfTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureVlanSfTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, VLAN_ID, PORT, PATH_ID_SMALL,
true);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// Check that configureVlanSfTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureVlanSfTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, VLAN_ID, PORT, PATH_ID_SMALL,
false);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// Check that configureVlanTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureVlanTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, VLAN_ID, PORT, PATH_ID);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// Check that configureVlanLastHopTransportEgressFlow() is written
// to the correct table and that it goes to TABLE_EGRESS
sfcOfFlowProgrammer.configureVlanLastHopTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, VLAN_ID, PORT, PATH_ID);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// checkGoToTable(curInstruction, TABLE_EGRESS, true);
}
/**
* Unit test to check application coexistence works for Mac Chaining flows.
*/
@Test
public void appCoexistenceMacChaining() {
sfcOfFlowProgrammer.setTableBase(TABLE_BASE);
sfcOfFlowProgrammer.setTableEgress(TABLE_EGRESS);
// When checking the table offsets, we need to subtract 2 to compensate
// for:
// - TABLE_INDEX_CLASSIFIER=0 - which is not used for AppCoexistence
// - TABLE_INDEX_TRANSPORT_INGRESS=1 - which is table 0 for
// AppCoexistence
// Example: tableBase=20, TABLE_INDEX_PATH_MAPPER=2, should return 20
// Check that configureMacChainingTransportIngressFlow() is written to the
// correct table
// Notice: TransportIngress doesn't use the offset, as it will always be
// table 0
sfcOfFlowProgrammer.configureMacChainingTransportIngressFlow(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), 0);
// Check that configureMacChainingNextHopFlow() is written to the correct table
VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(PATH_ID_SMALL, 0);
String vmac = hopMac.getHop(NSI).getValue();
String nextVmac = hopMac.getHop((short)(NSI - 1)).getValue();
sfcOfFlowProgrammer.configureMacChainingNextHopFlow(SFF_NAME, vmac, MAC_DST, nextVmac, false);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2);
Instruction curInstruction = flowBuilder.getInstructions().getInstruction().get(1).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2),
true);
// Check that configureMacChainingSfTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureMacChainingSfTransportEgressFlow(SFF_NAME, MAC_DST, PORT, null);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
}
/**
* Unit test to check application coexistence works for MPLS flows.
*/
@Test
public void appCoexistenceMpls() {
sfcOfFlowProgrammer.setTableBase(TABLE_BASE);
sfcOfFlowProgrammer.setTableEgress(TABLE_EGRESS);
// Check that configureMplsTransportIngressFlow() is written to the
// correct table
// Notice: TransportIngress doesnt use the offset, as it will always be
// table 0
sfcOfFlowProgrammer.configureMplsTransportIngressFlow(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(), 0);
Instruction curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER + TABLE_BASE - 2),
true);
// Check that configureMplsPathMapperFlow() is written to the correct
// table
sfcOfFlowProgrammer.configureMplsPathMapperFlow(SFF_NAME, MPLS_LABEL, PATH_ID_SMALL, true);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER + TABLE_BASE - 2);
// Check that configureMplsPathMapperFlow() is written to the correct
// table
sfcOfFlowProgrammer.configureMplsPathMapperFlow(SFF_NAME, MPLS_LABEL, PATH_ID, false);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER + TABLE_BASE - 2);
// Mpls NextHop uses MacNextHop which is tested in appCoexistenceVlan
// Check that configureMplsTransportEgressFlow() is written
// to the correct table and that it does NOT go to TABLE_EGRESS
sfcOfFlowProgrammer.configureMplsTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, MPLS_LABEL, PORT, PATH_ID);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// Check that configureMplsLastHopTransportEgressFlow() is written
// to the correct table and that it goes to TABLE_EGRESS
sfcOfFlowProgrammer.configureMplsLastHopTransportEgressFlow(SFF_NAME, MAC_SRC, MAC_DST, MPLS_LABEL, PORT,
PATH_ID);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
assertTrue(curInstruction instanceof ApplyActionsCase);
// checkGoToTable(curInstruction, TABLE_EGRESS, true);
}
/**
* Unit test to check application coexistence works for the MatchAny flows.
*/
@Test
public void appCoexistenceMatchAny() {
sfcOfFlowProgrammer.setTableBase(TABLE_BASE);
sfcOfFlowProgrammer.setTableEgress(TABLE_EGRESS);
// Test Classifier Match Any table offset.
// No flows should be written
sfcOfFlowProgrammer.configureClassifierTableMatchAny(SFF_NAME);
assertEquals(sfcOfFlowWriter.getFlowBuilder(), null);
// Test TransportIngress Match Any table offset.
// No flows should be written
sfcOfFlowProgrammer.configureTransportIngressTableMatchAny(SFF_NAME);
assertEquals(sfcOfFlowWriter.getFlowBuilder(), null);
// Test PathMapper Match Any table offset.
// It should go to PathMapperAcl + offset
sfcOfFlowProgrammer.configurePathMapperTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
Instruction curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER_ACL + TABLE_BASE - 2),
true);
// Test PathMapperAcl Match Any table offset.
// It should go to NextHop + offset
sfcOfFlowProgrammer.configurePathMapperAclTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER_ACL + TABLE_BASE - 2);
assertEquals(flowBuilder.getInstructions().getInstruction().size(), 1);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2), true);
// Test NextHop Match Any table offset.
// It should go to TransportEgress + offset
sfcOfFlowProgrammer.configureNextHopTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2),
true);
// Test TransportEgress Match Any table offset.
// It should do a drop
sfcOfFlowProgrammer.configureTransportEgressTableMatchAny(SFF_NAME);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_TRANSPORT_EGRESS + TABLE_BASE - 2);
curInstruction = flowBuilder.getInstructions().getInstruction().get(0).getInstruction();
checkDrop(curInstruction, true);
}
/**
* Unit test to check app coexistence works for the PathMapperAcl flows.
*/
@Test
public void appCoexistencePathMapperAcl() {
sfcOfFlowProgrammer.setTableBase(TABLE_BASE);
sfcOfFlowProgrammer.setTableEgress(TABLE_EGRESS);
sfcOfFlowProgrammer.configurePathMapperAclFlow(SFF_NAME, IP_SRC, IP_DST, (short) PATH_ID);
flowBuilder = sfcOfFlowWriter.getFlowBuilder();
assertEquals(flowBuilder.getTableId().shortValue(),
SfcOfFlowProgrammerImpl.TABLE_INDEX_PATH_MAPPER_ACL + TABLE_BASE - 2);
Instruction curInstruction = flowBuilder.getInstructions().getInstruction().get(1).getInstruction();
checkGoToTable(curInstruction, (short) (SfcOfFlowProgrammerImpl.TABLE_INDEX_NEXT_HOP + TABLE_BASE - 2), true);
}
private void checkGoToTable(Instruction curInstruction, short nextTableId) {
checkGoToTable(curInstruction, nextTableId, false);
}
private void checkGoToTable(Instruction curInstruction, short nextTableId, boolean mustExist) {
if (curInstruction instanceof GoToTableCase) {
GoToTableCase goToTablecase = (GoToTableCase) curInstruction;
assertEquals(goToTablecase.getGoToTable().getTableId().shortValue(), nextTableId);
} else {
if (mustExist) {
LOG.info("checkGoToTable expecting GoToTableCase, but received [{}]", curInstruction);
fail();
}
}
}
private void checkActionHasResubmit(Instruction curInstruction, short nextTableId) {
assertTrue(curInstruction instanceof ApplyActionsCase);
boolean resubmitActionFound = false;
for (Action action : ((ApplyActionsCase) curInstruction).getApplyActions().getAction()) {
LOG.info("checkActionHasResubmit : action [{}]", action.getAction());
if (action.getAction() instanceof NxActionResubmitNodesNodeTableFlowWriteActionsCase) {
NxActionResubmitNodesNodeTableFlowWriteActionsCase resubmitAction =
(NxActionResubmitNodesNodeTableFlowWriteActionsCase) action.getAction();
assertEquals(resubmitAction.getNxResubmit().getTable().shortValue(), nextTableId);
resubmitActionFound = true;
}
// ApplyActionsCase aac = (ApplyActionsCase) curInstruction;
}
assertTrue(resubmitActionFound);
}
private void checkDrop(Instruction curInstruction, boolean mustExist) {
if (curInstruction instanceof ApplyActionsCase) {
ApplyActionsCase action = (ApplyActionsCase) curInstruction;
DropActionCase drop = (DropActionCase) action.getApplyActions().getAction().get(0).getAction();
assertTrue(drop.getDropAction() != null);
} else {
if (mustExist) {
LOG.info("checkDrop expecting GoToTableCase, but received [{}]", curInstruction);
fail();
}
}
}
private void checkMetadata(Instruction curInstruction, long pathId) {
if (curInstruction instanceof WriteMetadataCase) {
WriteMetadataCase metadata = (WriteMetadataCase) curInstruction;
assertEquals(metadata.getWriteMetadata().getMetadata().longValue(), pathId);
}
}
private void checkMatchNsh(Flow flow, long nsp, short nsi) {
GeneralAugMatchNodesNodeTableFlow genAug =
flow.getMatch().getAugmentation(GeneralAugMatchNodesNodeTableFlow.class);
List<ExtensionList> extensions = genAug.getExtensionList();
for (ExtensionList extensionList : extensions) {
Extension extension = extensionList.getExtension();
NxAugMatchNodesNodeTableFlow nxAugMatch = extension.getAugmentation(NxAugMatchNodesNodeTableFlow.class);
if (nxAugMatch.getNxmNxNsp() != null) {
assertEquals(nxAugMatch.getNxmNxNsp().getValue().longValue(), NSP);
}
if (nxAugMatch.getNxmNxNsi() != null) {
assertEquals(nxAugMatch.getNxmNxNsi().getNsi().shortValue(), NSI);
}
}
}
}