\r
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;\r
\r
-import static org.junit.Assert.assertEquals;\r
-import static org.junit.Assert.assertTrue;\r
-import static org.mockito.Mockito.mock;\r
-import static org.mockito.Mockito.when;\r
-\r
-import org.junit.Assert;\r
+import com.google.common.base.Preconditions;\r
import org.junit.Before;\r
import org.junit.Test;\r
+import org.mockito.ArgumentCaptor;\r
+import org.mockito.Captor;\r
+import org.opendaylight.groupbasedpolicy.dto.EgKey;\r
+import org.opendaylight.groupbasedpolicy.dto.PolicyInfo;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager;\r
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;\r
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.policyenforcer.NetworkElements;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader;\r
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader.SfcNshHeaderBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlanGpe;\r
\r
-public class ChainActionFlowsTest {\r
+import java.math.BigInteger;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import static org.junit.Assert.assertArrayEquals;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.mockito.Mockito.any;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.times;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxNsiMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxNspMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxTunIdMatch;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.base;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadNshc1RegAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadNshc2RegAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction;\r
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;\r
\r
- private SfcNshHeader sfcNshHeader;\r
- private NodeConnectorId tunPort;\r
- private NetworkElements netElements;\r
- private PolicyManager policyManager;\r
- private SwitchManager switchManager;\r
- private Ipv4Address ip1 = new Ipv4Address("10.1.1.1");\r
- private Ipv4Address ip2 = new Ipv4Address("10.1.1.2");\r
+public class ChainActionFlowsTest extends MapperUtilsTest {\r
+\r
+ @Captor\r
+ private final ArgumentCaptor<NodeId> nodeIdCaptor = ArgumentCaptor.forClass(NodeId.class);\r
+ private final ArgumentCaptor<Short> tableIdCaptor = ArgumentCaptor.forClass(Short.class);\r
+ private final ArgumentCaptor<Flow> flowCaptor = ArgumentCaptor.forClass(Flow.class);\r
\r
@Before\r
- public void setup() {\r
- policyManager = mock(PolicyManager.class);\r
+ public void init() {\r
+ ctx = mock(OfContext.class);\r
+ endpointManager = mock(EndpointManager.class);\r
switchManager = mock(SwitchManager.class);\r
- EndpointFwdCtxOrdinals ords = mock(EndpointFwdCtxOrdinals.class);\r
- sfcNshHeader = mock(SfcNshHeader.class);\r
- netElements = mock(NetworkElements.class);\r
- when(netElements.getSrcNodeId()).thenReturn(new NodeId("openflow:1"));\r
- when(netElements.getSrcEpOrdinals()).thenReturn(ords);\r
- when(netElements.getSrcEpOrdinals().getL3Id()).thenReturn(7);\r
- when(netElements.getDstNodeId()).thenReturn(new NodeId("openflow:1"));\r
- when(netElements.getDstEpOrdinals()).thenReturn(ords);\r
- when(netElements.getDstEpOrdinals().getL3Id()).thenReturn(7);\r
- when(netElements.getLocalNodeId()).thenReturn(new NodeId("openflow:1"));\r
- tunPort = new NodeConnectorId("openflow:1:42");\r
+ policyManager = mock(PolicyManager.class);\r
+ policyInfo = mock(PolicyInfo.class);\r
+ ofWriter = mock(OfWriter.class);\r
}\r
\r
@Test\r
- public void createExternalFlowTest() throws Exception {\r
- // Note C1 != tunDest ie ip1 and ip2 - output action\r
- sfcNshHeader = new SfcNshHeaderBuilder().setNshMetaC1(SfcNshHeader.convertIpAddressToLong(ip1))\r
- .setNshTunIpDst(ip2)\r
- .setNshMetaC2(7L)\r
- .setNshNsiToChain((short) 1)\r
- .build();\r
-\r
- Flow flow = ChainActionFlows.createExternalFlow(sfcNshHeader, tunPort, netElements, policyManager, switchManager, ip2);\r
- assertEquals(policyManager.getTABLEID_EXTERNAL_MAPPER(), flow.getTableId().shortValue());\r
- assertTrue(flow.getInstructions().getInstruction()\r
- .get(0).getInstruction().toString().contains("_outputAction=OutputAction"));\r
-\r
- // Note C1 == tunDest ie ip1\r
- sfcNshHeader = new SfcNshHeaderBuilder().setNshMetaC1(SfcNshHeader.convertIpAddressToLong(ip1))\r
- .setNshTunIpDst(ip1)\r
- .setNshMetaC2(7L)\r
- .setNshNsiToChain((short) 1)\r
- .build();\r
-\r
- flow = ChainActionFlows.createExternalFlow(sfcNshHeader, tunPort, netElements, policyManager, switchManager, ip2);\r
-\r
- assertTrue(flow.getInstructions().getInstruction()\r
- .get(0).getInstruction().toString().contains("_outputAction=OutputAction"));\r
+ public void createChainTunnelFlows_directionIn() throws Exception {\r
+ // Tenant\r
+ TenantBuilder tenantBuilder = buildTenant();\r
+ Tenant tenant = tenantBuilder.build();\r
+ // Source Endpoint\r
+ EndpointBuilder sourceEndpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);\r
+ Endpoint sourceEndpoint = sourceEndpointBuilder.build();\r
+ EgKey sourceEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_0);\r
+ // Destination Endpoint\r
+ EndpointBuilder destinationEndpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);\r
+ Endpoint destinationEndpoint = destinationEndpointBuilder.build();\r
+ EgKey destinationEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_1);\r
+ // Nsh header\r
+ SfcNshHeaderBuilder nshHeaderBuilder = new SfcNshHeaderBuilder();\r
+ nshHeaderBuilder.setNshNsiFromChain((short) 250);\r
+ nshHeaderBuilder.setNshNspFromChain(27L);\r
+ SfcNshHeader nshHeader = nshHeaderBuilder.build();\r
+\r
+ when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());\r
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);\r
+ when(ctx.getSwitchManager()).thenReturn(switchManager);\r
+ when(ctx.getPolicyManager()).thenReturn(policyManager);\r
+ when(ctx.getCurrentPolicy()).thenReturn(policyInfo);\r
+ when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(CONNECTOR_2);\r
+ when(switchManager.getTunnelIP(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(new IpAddress(IPV4_2));\r
+ when(policyManager.getTABLEID_PORTSECURITY()).thenReturn((short) 4);\r
+ when(policyManager.getTABLEID_SOURCE_MAPPER()).thenReturn((short) 2);\r
+\r
+ // Net elements\r
+ NetworkElements netElements = new NetworkElements(sourceEndpoint, destinationEndpoint, sourceEgKey,\r
+ destinationEgKey, NODE_ID, ctx);\r
+ assertNotNull(netElements);\r
+\r
+ ChainActionFlows.createChainTunnelFlows(nshHeader, netElements, ofWriter, ctx, HasDirection.Direction.In);\r
+\r
+ // Verify flows and capture arguments\r
+ verify(ofWriter, times(4)).writeFlow(nodeIdCaptor.capture(), tableIdCaptor.capture(), flowCaptor.capture());\r
+\r
+ // Verify nodeIds\r
+ for (NodeId capturedNodeId : nodeIdCaptor.getAllValues()) {\r
+ assertEquals(capturedNodeId, NODE_ID);\r
+ }\r
+\r
+ // Verify tableIds\r
+ List<Short> tableIds = tableIdCaptor.getAllValues();\r
+ Short expectedTableIds[] = {4, 2, 0, 2};\r
+ assertArrayEquals(expectedTableIds, tableIds.toArray());\r
+\r
+ // Verify flows\r
+ List<Flow> flows = flowCaptor.getAllValues();\r
+ assertNotNull(flows);\r
+ assertTrue(flows.size() == 4);\r
+ assertEquals(flows.get(0), allowFromChainTestFlow());\r
+ assertEquals(flows.get(1), createChainTunnelTestFlow(netElements).get(0)); // contains only 1 entry\r
+ assertEquals(flows.get(2), allowFromChainTunnelTestFlow());\r
+ assertEquals(flows.get(3), createChainBroadcastTestFlow());\r
}\r
\r
@Test\r
- public void returnOfPortFromNodeConnectorTest() {\r
- NodeConnectorId ncId = new NodeConnectorId("openflow:1:42");\r
- Integer port = ChainActionFlows.returnOfPortFromNodeConnector(ncId);\r
- assertEquals(new Integer("42"), port);\r
+ public void createChainTunnelFlows_directionOut() throws Exception {\r
+ // Tenant\r
+ TenantBuilder tenantBuilder = buildTenant();\r
+ Tenant tenant = tenantBuilder.build();\r
+ // Source Endpoint\r
+ EndpointBuilder sourceEndpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0);\r
+ Endpoint sourceEndpoint = sourceEndpointBuilder.build();\r
+ EgKey sourceEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_0);\r
+ // Destination Endpoint\r
+ EndpointBuilder destinationEndpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1);\r
+ Endpoint destinationEndpoint = destinationEndpointBuilder.build();\r
+ EgKey destinationEgKey = new EgKey(tenant.getId(), ENDPOINT_GROUP_1);\r
+ // Nsh header\r
+ SfcNshHeaderBuilder nshHeaderBuilder = new SfcNshHeaderBuilder();\r
+ nshHeaderBuilder.setNshNsiToChain((short) 255);\r
+ nshHeaderBuilder.setNshNspToChain(27L);\r
+ nshHeaderBuilder.setNshTunIpDst(IPV4_2);\r
+ SfcNshHeader nshHeader = nshHeaderBuilder.build();\r
+\r
+ when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant());\r
+ when(ctx.getEndpointManager()).thenReturn(endpointManager);\r
+ when(ctx.getSwitchManager()).thenReturn(switchManager);\r
+ when(ctx.getPolicyManager()).thenReturn(policyManager);\r
+ when(ctx.getCurrentPolicy()).thenReturn(policyInfo);\r
+ when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(CONNECTOR_2);\r
+ when(switchManager.getTunnelIP(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(new IpAddress(IPV4_2));\r
+ when(policyManager.getTABLEID_EXTERNAL_MAPPER()).thenReturn((short) 6);\r
+\r
+\r
+ // Net elements\r
+ NetworkElements netElements = new NetworkElements(sourceEndpoint, destinationEndpoint, sourceEgKey,\r
+ destinationEgKey, NODE_ID, ctx);\r
+ assertNotNull(netElements);\r
+\r
+ ChainActionFlows.createChainTunnelFlows(nshHeader, netElements, ofWriter, ctx, HasDirection.Direction.Out);\r
+\r
+ // Verify flows and capture arguments\r
+ verify(ofWriter, times(1)).writeFlow(NODE_ID, (short) 6, createExternalTestFlow());\r
+ }\r
+\r
+ private Flow allowFromChainTestFlow() {\r
+ MatchBuilder matchBuilder = new MatchBuilder();\r
+ FlowUtils.addNxNshc1RegMatch(matchBuilder, 0L);\r
+ FlowUtils.addNxNsiMatch(matchBuilder, (short) 250);\r
+ FlowUtils.addNxNspMatch(matchBuilder, 27L);\r
+ Match match = matchBuilder.setInPort(CONNECTOR_2).build();\r
+\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 4, "chainport", match);\r
+ FlowBuilder flowBuilder = new FlowBuilder().setTableId((short) 4).setBarrier(false).setHardTimeout(0)\r
+ .setIdleTimeout(0).setId(flowId).setPriority(1200).setMatch(match)\r
+ .setInstructions(FlowUtils.gotoTableInstructions((short) 2));\r
+ return flowBuilder.build();\r
+ }\r
+\r
+ private List<Flow> createChainTunnelTestFlow(NetworkElements networkElements) {\r
+ Preconditions.checkNotNull(networkElements);\r
+ List<Flow> flows = new ArrayList<>();\r
+ Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1L));\r
+ Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0xffffff));\r
+ Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(0L));\r
+ Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0L));\r
+ Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(0L));\r
+ for (L3Address address : networkElements.getDstEp().getL3Address()) {\r
+ Layer3Match l3Match = new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(address.getIpAddress()\r
+ .getIpv4Address().getValue() + IP_PREFIX_32)).build();\r
+ MatchBuilder mb = new MatchBuilder().setInPort(CONNECTOR_2).setLayer3Match(l3Match)\r
+ .setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4));\r
+ addNxTunIdMatch(mb, 2);\r
+ addNxNspMatch(mb, 27L);\r
+ addNxNsiMatch(mb, (short) 250);\r
+ Match match = mb.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 2, "chaintunnel", match);\r
+ FlowBuilder flowBuilder = base((short) 2).setId(flowId).setPriority(150).setMatch(match).setInstructions(\r
+ instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),\r
+ gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));\r
+ flows.add(flowBuilder.build());\r
+ }\r
+ assertTrue(flows.size() == 1);\r
+ return flows;\r
+ }\r
+\r
+ private Flow allowFromChainTunnelTestFlow() {\r
+ MatchBuilder matchBuilder = new MatchBuilder().setInPort(CONNECTOR_2);\r
+ addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg1.class, 0xffffffL));\r
+ Match match = matchBuilder.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 0, "chainport", match);\r
+ FlowBuilder flowBuilder = base((short) 0).setId(flowId).setMatch(match)\r
+ .setPriority(65000).setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));\r
+ return flowBuilder.build();\r
+ }\r
+\r
+ private Flow createChainBroadcastTestFlow() {\r
+ MatchBuilder matchBuilder = new MatchBuilder().setInPort(CONNECTOR_2);\r
+ addNxNsiMatch(matchBuilder, (short) 250);\r
+ addNxNspMatch(matchBuilder, 27L);\r
+ addNxTunIdMatch(matchBuilder, 0);\r
+ Match match = matchBuilder.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId((short) 2, "chainbroadcast", match);\r
+ FlowBuilder flowBuilder = base((short) 2).setId(flowId).setPriority(150).setMatch(match)\r
+ .setInstructions(instructions(applyActionIns(nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0))),\r
+ gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));\r
+ return flowBuilder.build();\r
+ }\r
+\r
+ private Flow createExternalTestFlow() {\r
+ Action loadC1 = nxLoadNshc1RegAction(null);\r
+ Action loadC2 = nxLoadNshc2RegAction(2L);\r
+ Action loadChainTunVnId = nxLoadTunIdAction(BigInteger.valueOf(2L), false);\r
+ Action loadChainTunDest = nxLoadTunIPv4Action(IPV4_2.getValue(), false);\r
+ Action outputAction = FlowUtils.createActionResubmit(null, (short) 0);\r
+\r
+ MatchBuilder matchBuilder = new MatchBuilder();\r
+ addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, 0L));\r
+ addNxTunIdMatch(matchBuilder, 2);\r
+ addNxNspMatch(matchBuilder, 27L);\r
+ addNxNsiMatch(matchBuilder, (short) 255);\r
+\r
\r
- ncId = new NodeConnectorId("openflow:1");\r
- Assert.assertNull(ChainActionFlows.returnOfPortFromNodeConnector(ncId));\r
+ Match match = matchBuilder.build();\r
+ FlowId flowId = FlowIdUtils.newFlowId(((short) 6), "chainexternal", match);\r
+ FlowBuilder flowBuilder = base((short) 6).setId(flowId).setPriority(1000).setMatch(match)\r
+ .setInstructions(instructions(applyActionIns(loadC1, loadC2, loadChainTunDest, loadChainTunVnId,\r
+ outputAction)));\r
+ return flowBuilder.build();\r
}\r
}\r