From 517c73ccf53b7ae107c4f0f1fd1ee69d8a65ac0f Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Mon, 21 Mar 2016 15:04:52 +0100 Subject: [PATCH 1/1] Bug 5617: OfOverlay Refactoring - Destination mapper Signed-off-by: Vladimir Lavor Change-Id: I7e1ac58b066f8eda1a5c989d1980459ee22a1960 --- .../ofoverlay/endpoint/EndpointManager.java | 23 + .../renderer/ofoverlay/flow/FlowTable.java | 4 +- .../renderer/ofoverlay/flow/FlowUtils.java | 20 + .../ofoverlay/flow/OrdinalFactory.java | 14 +- .../mapper/destination/DestinationMapper.java | 1572 +++-------------- .../destination/DestinationMapperFlows.java | 714 ++++++++ .../destination/DestinationMapperUtils.java | 160 ++ .../mapper/external/ExternalMapper.java | 30 +- .../mapper/ingressnat/IngressNatMapper.java | 16 +- .../ingressnat/IngressNatMapperFlows.java | 16 +- .../ofoverlay/mapper/source/SourceMapper.java | 15 +- .../ofoverlay/flow/DestinationMapperTest.java | 324 ---- .../ofoverlay/flow/FlowTableTest.java | 2 +- .../ofoverlay/flow/GroupTableTest.java | 10 +- .../ofoverlay/mapper/MapperUtilsTest.java | 311 ++-- .../DestinationMapperFlowsTest.java | 1215 +++++++++++++ .../destination/DestinationMapperTest.java | 433 +++++ .../DestinationMapperUtilsTest.java | 330 ++++ .../egressnat/EgressNatMapperFlowsTest.java | 51 +- .../mapper/egressnat/EgressNatMapperTest.java | 5 +- .../mapper/external/ExternalMapperTest.java | 206 +-- .../ingressnat/IngressNatMapperFlowsTest.java | 87 +- .../ingressnat/IngressNatMapperTest.java | 15 +- .../policyenforcer/PolicyEnforcerTest.java | 143 +- .../portsecurity/PortSecurityFlowsTest.java | 104 +- .../mapper/portsecurity/PortSecurityTest.java | 25 +- .../mapper/source/SourceMapperFlowsTest.java | 60 +- .../mapper/source/SourceMapperTest.java | 43 +- 28 files changed, 3728 insertions(+), 2220 deletions(-) create mode 100644 renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlows.java create mode 100644 renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtils.java delete mode 100755 renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java create mode 100644 renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlowsTest.java create mode 100644 renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperTest.java create mode 100644 renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtilsTest.java diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/endpoint/EndpointManager.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/endpoint/EndpointManager.java index 81bc50c2b..aa8124b72 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/endpoint/EndpointManager.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/endpoint/EndpointManager.java @@ -38,8 +38,10 @@ import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; import org.opendaylight.groupbasedpolicy.util.IidFactory; import org.opendaylight.groupbasedpolicy.util.SetUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointFields; @@ -640,6 +642,27 @@ public class EndpointManager implements AutoCloseable { return endpoints.getEndpointL3(); } + /** + * Reads L2 endpoint from data store using appropriate {@link EndpointL3} + * + * @return {@link EndpointL3} if exists, otherwise null + */ + public Endpoint getL2EndpointFromL3(EndpointL3 endpointL3) { + if(endpointL3 != null) { + L2BridgeDomainId l2Context = endpointL3.getL2Context(); + MacAddress macAddress = endpointL3.getMacAddress(); + if (l2Context == null || macAddress == null) { + LOG.debug("[L2Context: {}, MacAddress: {}] Cannot read endpoint from DS unless both keys are specified!", + l2Context, macAddress); + return null; + } + EpKey l2EndpointKey = new EpKey(l2Context, macAddress); + return endpoints.get(l2EndpointKey); + } + + return null; + } + /** * Reads endpointL3 from data store * @param l3c id of {@link L3Context} diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTable.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTable.java index fadcc6e32..743c519cd 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTable.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTable.java @@ -8,14 +8,13 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns; - import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; 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.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,5 +81,4 @@ public abstract class FlowTable extends OfTable { flowb.setId(flowid); return flowb.build(); } - } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowUtils.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowUtils.java index 53e471769..4ae1d3e6f 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowUtils.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowUtils.java @@ -794,4 +794,24 @@ public final class FlowUtils { .setHardTimeout(0) .setIdleTimeout(0); } + + /** + * Convert string value to byte array + * + * @param values input value as a (@link String) + * @return byte representation of input data + */ + public static byte[] bytesFromHexString(String values) { + String target = ""; + if (values != null) { + target = values; + } + String[] octets = target.split(":"); + + byte[] ret = new byte[octets.length]; + for (int i = 0; i < octets.length; i++) { + ret[i] = Integer.valueOf(octets[i], 16).byteValue(); + } + return ret; + } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OrdinalFactory.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OrdinalFactory.java index 9d5ad4f51..2658b6850 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OrdinalFactory.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OrdinalFactory.java @@ -55,9 +55,8 @@ public class OrdinalFactory { * @param tenantId the tenant id * @param id a unique id * @return the ordinal - * @throws Exception throws all exception */ - public static int getContextOrdinal(final TenantId tenantId, final UniqueId id) throws Exception { + public static int getContextOrdinal(final TenantId tenantId, final UniqueId id) { if (tenantId == null || id == null) return 0; return getContextOrdinalFromString(tenantId.getValue() + "|" + id.getValue()); @@ -98,7 +97,7 @@ public class OrdinalFactory { return getContextOrdinalFromString(destNode.getValue()); } - public static int getContextOrdinal(Endpoint ep, NetworkDomainId networkContainment) throws Exception { + public static int getContextOrdinal(Endpoint ep, NetworkDomainId networkContainment) { Set epgs = new TreeSet<>(); @@ -125,7 +124,7 @@ public class OrdinalFactory { } - public static int getContextOrdinal(Endpoint ep) throws Exception { + public static int getContextOrdinal(Endpoint ep) { Set epgs = new TreeSet<>(); @@ -158,7 +157,7 @@ public class OrdinalFactory { * the unique ID for the element * @return the 32-bit ordinal value */ - private static int getContextOrdinalFromString(final String id) throws Exception { + private static int getContextOrdinalFromString(final String id) { Integer ord = ordinals.get(id); if (ord == null) { @@ -171,7 +170,7 @@ public class OrdinalFactory { } public static final EndpointFwdCtxOrdinals getEndpointFwdCtxOrdinals(OfContext ctx, - Endpoint ep) throws Exception { + Endpoint ep) { IndexedTenant tenant = ctx.getTenant(ep.getTenant()); if (tenant == null) { LOG.debug("Tenant {} is null", ep.getTenant()); @@ -187,7 +186,7 @@ public class OrdinalFactory { private EpKey ep; private int epgId = 0, bdId = 0, fdId = 0, l3Id = 0, cgId = 0, tunnelId = 0; - private EndpointFwdCtxOrdinals(Endpoint ep, OfContext ctx) throws Exception { + private EndpointFwdCtxOrdinals(Endpoint ep, OfContext ctx) { this.ep = new EpKey(ep.getL2Context(), ep.getMacAddress()); IndexedTenant tenant = ctx.getTenant(ep.getTenant()); @@ -269,6 +268,7 @@ public class OrdinalFactory { } @VisibleForTesting + // Used only for unit testing public static void resetPolicyOrdinalValue() { policyOrdinal.set(1); } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapper.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapper.java index c613359b3..5597a1a1c 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapper.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapper.java @@ -8,98 +8,36 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.destination; -import static com.google.common.base.Preconditions.checkNotNull; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv4; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.IPv6; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.groupAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpOpAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpShaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpSpaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpShaToArpThaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpSpaToArpTpaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveEthSrcToEthDstAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlDstAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlSrcAction; -import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; - -import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; import org.opendaylight.groupbasedpolicy.dto.EgKey; import org.opendaylight.groupbasedpolicy.dto.EpKey; import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals; -import org.opendaylight.groupbasedpolicy.util.IidFactory; -import org.opendaylight.groupbasedpolicy.util.TenantUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; -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.InstructionsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4; @@ -107,15 +45,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; -import com.google.common.base.Strings; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; /** *

Manage the table that maps the destination address to the next hop for the @@ -144,10 +85,11 @@ import com.google.common.collect.Sets; * L3 flows: *

* External, local and remote L3 routed flows:
- * Priority = 50
+ * Priority = 132
* Matches:
* - ip (ethertype) * - dl_dst mac address {@link MacAddress}
+ * - nw_dst ip address {@link IpAddress}
* - setReg6 {@link NxmNxReg6}
* Actions:
* - loadReg2 {@link NxmNxReg2}
@@ -202,1303 +144,355 @@ import com.google.common.collect.Sets; */ public class DestinationMapper extends FlowTable { - protected static final Logger LOG = LoggerFactory.getLogger(DestinationMapper.class); + private static final Logger LOG = LoggerFactory.getLogger(DestinationMapper.class); - // TODO Li alagalah: Improve UT coverage for this class. + private final DestinationMapperUtils utils; + private final short tableId; - // TODO Li alagalah: Use EndpointL3 for L3 flows, Endpoint for L2 flows - // This ensures we have the appropriate network-containment' + final Map> subnetsByTenant = new HashMap<>(); - public static short TABLE_ID; - /** - * This is the MAC address of the magical router in the sky - */ + // This is the MAC address of the magical router in the sky public static final MacAddress ROUTER_MAC = new MacAddress("88:f0:31:b5:12:b5"); - public static final MacAddress MULTICAST_MAC = new MacAddress("01:00:00:00:00:00"); - public static final Integer BASE_L3_PRIORITY = 100; + private static final MacAddress MULTICAST_MAC = new MacAddress("01:00:00:00:00:00"); + private static final int EXTERNAL_L2 = 50; + private static final int LOCAL_L2 = 50; + private static final int L3_PREFIX = 100; + private static final int L3_LOCAL = 132; + private static final int L3_EXTERNAL = 132; + private static final int ROUTER_ARP = 150; + private static final int REMOTE_L2 = 50; + private static final int REMOTE_L3 = 132; + // Priorities + private static final int DROP_FLOW = 1; + private static final int BROADCAST = 140; public DestinationMapper(OfContext ctx, short tableId) { super(ctx); - this.TABLE_ID = tableId; + this.tableId = tableId; + utils = new DestinationMapperUtils(ctx); } - Map> subnetsByTenant = new HashMap>(); - @Override public short getTableId() { - return TABLE_ID; + return tableId; } @Override public void sync(Endpoint endpoint, OfWriter ofWriter) throws Exception { + NodeId endpointNodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint); + if (endpointNodeId == null) { + LOG.warn("Endpoint {} has no location specified, skipped", endpoint); + return; + } + DestinationMapperFlows flows = new DestinationMapperFlows(utils, endpointNodeId, tableId); - // TODO: only temporary workaround, use src & dst endpoint in implementation - NodeId nodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint); + // Do sync + syncFlows(flows, endpoint, endpointNodeId, ofWriter); + } - TenantId currentTenant = null; + @VisibleForTesting + void syncFlows(DestinationMapperFlows flows, Endpoint endpoint, NodeId nodeId, OfWriter ofWriter) { - ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID)); + // Create basic drop flow + flows.dropFlow(DROP_FLOW, null, ofWriter); - SetMultimap visitedEps = HashMultimap.create(); - Set epOrdSet = new HashSet<>(); + // Sync flows related to endpoints + List localSubnets = utils.getLocalSubnets(nodeId); + if (localSubnets != null) { + // Local + syncLocalFlows(flows, endpoint, localSubnets, ofWriter); + // Remote & external + syncEndpointFlows(flows, nodeId, endpoint, ofWriter); + } - for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) { - Set srcEpgIds = new HashSet<>(); - if (srcEp.getEndpointGroup() != null) - srcEpgIds.add(srcEp.getEndpointGroup()); - if (srcEp.getEndpointGroups() != null) - srcEpgIds.addAll(srcEp.getEndpointGroups()); + // Sync router ARP flow + TenantId tenantId = endpoint.getTenant(); + syncArpFlow(flows, tenantId, ofWriter); - for (EndpointGroupId epgId : srcEpgIds) { - EgKey epg = new EgKey(srcEp.getTenant(), epgId); - Set peers = Sets.union(Collections.singleton(epg), ctx.getCurrentPolicy().getPeers(epg)); - for (EgKey peer : peers) { - Collection endpointsForGroup = new HashSet<>(); - endpointsForGroup.addAll(ctx.getEndpointManager().getEndpointsForGroup(peer)); - endpointsForGroup.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)); - for (Endpoint peerEp : endpointsForGroup) { - currentTenant = peerEp.getTenant(); - subnetsByTenant.put(currentTenant, getSubnets(currentTenant)); - EpKey srcEpKey = new EpKey(srcEp.getL2Context(), srcEp.getMacAddress()); - EpKey peerEpKey = new EpKey(peerEp.getL2Context(), peerEp.getMacAddress()); + // Create broadcast flow + EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); + if (ordinals != null) { + flows.createBroadcastFlow(BROADCAST, ordinals, MULTICAST_MAC, ofWriter); + } - if (visitedEps.get(srcEpKey) != null && visitedEps.get(srcEpKey).contains(peerEpKey)) { - continue; - } - syncEP(ofWriter, nodeId, srcEp, peerEp); - visitedEps.put(srcEpKey, peerEpKey); + // L3 Prefix Endpoint handling + Collection prefixes = ctx.getEndpointManager().getEndpointsL3PrefixForTenant(tenantId); + if (prefixes != null) { + LOG.trace("DestinationMapper - Processing L3PrefixEndpoint"); + syncL3PrefixFlow(flows, prefixes, tenantId, nodeId, ofWriter); + } + } - // Process subnets and flood-domains for epPeer - EndpointFwdCtxOrdinals epOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, - peerEp); - if (epOrds == null) { - LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", peerEp); - continue; - } + @VisibleForTesting + void syncEndpointFlows(DestinationMapperFlows flows, NodeId nodeId, Endpoint endpoint, OfWriter ofWriter) { + SetMultimap visited = HashMultimap.create(); + Set groupIds = utils.getAllEndpointGroups(endpoint); + for (EndpointGroupId groupId : groupIds) { + EgKey groupKey = new EgKey(endpoint.getTenant(), groupId); + Set peers = Sets.union(Collections.singleton(groupKey), + ctx.getCurrentPolicy().getPeers(groupKey)); + for (EgKey peer : peers) { + Collection endpointsForGroup = new HashSet<>(); + endpointsForGroup.addAll(ctx.getEndpointManager().getEndpointsForGroup(peer)); + endpointsForGroup.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)); + for (Endpoint peerEndpoint : endpointsForGroup) { + subnetsByTenant.put(peerEndpoint.getTenant(), utils.getSubnets(endpoint.getTenant())); + EpKey epKey = new EpKey(endpoint.getL2Context(), endpoint.getMacAddress()); + EpKey peerEpKey = new EpKey(peerEndpoint.getL2Context(), peerEndpoint.getMacAddress()); + if (visited.get(epKey) != null && visited.get(epKey).contains(peerEpKey)) { + continue; + } + // Basic checks + IndexedTenant endpointTenant = utils.getIndexedTenant(endpoint.getTenant()); + IndexedTenant peerTenant = utils.getIndexedTenant(peerEndpoint.getTenant()); + if (endpointTenant == null || peerTenant == null) { + LOG.debug("Source or destination endpoint references empty tenant. SrcEp: {} DestEp: {}", + endpointTenant, peerTenant); + continue; + } + EndpointFwdCtxOrdinals endpointOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); + EndpointFwdCtxOrdinals peerOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEndpoint); + if (endpointOrdinals == null || peerOrdinals == null) { + LOG.debug("Source od destination endpoint ordinals are null. SrcOrdinals: {} DestOrdinals: {}", + endpointOrdinals, peerOrdinals); + continue; + } - epOrdSet.add(epOrds); + if (peerEndpoint.getEndpointGroup() == null && peerEndpoint.getEndpointGroups() == null) { + LOG.debug("Didn't process endpoint {} due to EPG(s) being null", peerEndpoint.getKey()); + continue; } - } - } - } - for (Entry> subnetEntry : subnetsByTenant.entrySet()) { - if (subnetEntry.getValue() == null) { - LOG.trace("Tenant: {} has empty subnet entry.", subnetEntry.getKey()); - continue; - } - currentTenant = subnetEntry.getKey(); - for (Subnet sn : subnetEntry.getValue()) { - L3Context l3c = getL3ContextForSubnet(currentTenant, sn); - Flow arpFlow = createRouterArpFlow(currentTenant, nodeId, sn, - OrdinalFactory.getContextOrdinal(currentTenant, l3c.getId())); - if (arpFlow != null) { - ofWriter.writeFlow(nodeId, TABLE_ID, arpFlow); - } else { - LOG.debug( - "Gateway ARP flow is not created, because virtual router IP has not been set for subnet {} .", - sn.getIpPrefix().getValue()); - } - } - } + List localSubnets = utils.getLocalSubnets(nodeId); + if (localSubnets == null) { + LOG.error("No subnets could be found locally for node: {}", nodeId); + continue; + } + OfOverlayContext peerContext = peerEndpoint.getAugmentation(OfOverlayContext.class); + Subnet epSubnet = endpointTenant.resolveSubnet(new SubnetId(endpoint.getNetworkContainment())); + Endpoint l2GatewayEp = utils.getL2EpOfSubnetGateway(endpoint.getTenant(), epSubnet); + boolean peerEpIsExternal = peerEndpoint.getNetworkContainment() != null + && EndpointManager.isExternal(peerEndpoint, peerTenant.getExternalImplicitGroups()); + boolean subnetGwIsExternal = l2GatewayEp != null && EndpointManager.isExternal(l2GatewayEp, + utils.getIndexedTenant(endpoint.getTenant()).getExternalImplicitGroups()); + // Sync external + if (peerEpIsExternal || subnetGwIsExternal) { + Set externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); + syncExternalFlows(flows, endpoint, peerEndpoint, l2GatewayEp, externalPorts, ofWriter); + // Sync remote + } else if (peerContext != null && !Objects.equals(peerContext.getNodeId(), nodeId)) { + syncRemoteFlows(flows, endpoint, peerEndpoint, peerContext, nodeId, endpointOrdinals, peerOrdinals, localSubnets, ofWriter); + } - // Write broadcast flows per flood domain. - for (EndpointFwdCtxOrdinals epOrd : epOrdSet) { - if (ofWriter.groupExists(nodeId, Integer.valueOf(epOrd.getFdId()).longValue())) { - ofWriter.writeFlow(nodeId, TABLE_ID, createBroadcastFlow(epOrd)); + visited.put(epKey, peerEpKey); + } } } + } - // L3 Prefix Endpoint handling - Collection prefixEps = ctx.getEndpointManager().getEndpointsL3PrefixForTenant(currentTenant); - if (prefixEps != null) { - LOG.trace("DestinationMapper - Processing L3PrefixEndpoints"); - for (EndpointL3Prefix prefixEp : prefixEps) { - List localSubnets = getLocalSubnets(nodeId); - if (localSubnets == null) { + @VisibleForTesting + void syncArpFlow(DestinationMapperFlows flows, TenantId tenantId, OfWriter ofWriter) { + for (Entry> subnetEntry : subnetsByTenant.entrySet()) { + for (Subnet subnet : subnetEntry.getValue()) { + IndexedTenant tenant = ctx.getTenant(tenantId); + L3Context l3Context = utils.getL3ContextForSubnet(tenant, subnet); + if (subnet == null || subnet.getVirtualRouterIp() == null) { + LOG.trace("Arp flow not created, subnet or its virtual router is null. Subnet Id: {}", subnet); continue; } - for (Subnet localSubnet: localSubnets) { - Flow prefixFlow = createL3PrefixFlow(prefixEp, nodeId, localSubnet); - if (prefixFlow != null) { - ofWriter.writeFlow(nodeId, TABLE_ID, prefixFlow); - LOG.trace("Wrote L3Prefix flow"); + try { + if (l3Context != null && l3Context.getId() != null && tenant != null) { + flows.createRouterArpFlow(ROUTER_ARP, tenant, subnet, ofWriter); } + } catch (Exception e) { + LOG.error("Failed to get context ordinal from tenant Id {} and L3 Context Id {}", tenantId, + l3Context.getId()); } } } } - - - // set up next-hop destinations for all the endpoints in the endpoint - // group on the node - - private Flow createL3PrefixFlow(EndpointL3Prefix prefixEp, NodeId nodeId, Subnet subnet) throws Exception { - /* - * Priority: 100+lengthprefix - * Match: prefix, l3c, "mac address of router" ? - * Action: - * - set Reg2, Reg3 for L3Ep by L2Ep ? - * - if external, - * - Reg7: use switch location external port else punt for now - * - if internal - * - Reg7: grab L2Ep from L3Ep and use its location info - * - goto_table: POLENF (will check there for external on EP) - */ - - ReadOnlyTransaction rTx = ctx.getDataBroker().newReadOnlyTransaction(); - // TODO Bug #3440 Target: Be - should support for more than first gateway. - EndpointL3Gateways l3Gateway = prefixEp.getEndpointL3Gateways().get(0); - Optional optL3Ep = readFromDs(LogicalDatastoreType.OPERATIONAL, - IidFactory.l3EndpointIid(l3Gateway.getL3Context(), l3Gateway.getIpAddress()), rTx); - if (!optL3Ep.isPresent()) { - LOG.error("createL3PrefixFlow - L3Endpoint gateway {} for L3Prefix {} not found.", l3Gateway, prefixEp); - return null; - } - EndpointL3 l3Ep = optL3Ep.get(); - if (l3Ep.getL2Context() == null || l3Ep.getMacAddress() == null) { - LOG.debug("L3 endpoint representing L3 gateway does not contain L2-context or MAC address. {}", l3Ep); - return null; - } - Optional optL2Ep = readFromDs(LogicalDatastoreType.OPERATIONAL, - IidFactory.endpointIid(l3Ep.getL2Context(), l3Ep.getMacAddress()), rTx); - if (!optL2Ep.isPresent()) { - LOG.error("createL3PrefixFlow - L2Endpoint for L3Gateway {} not found.", l3Ep); - return null; - } - Endpoint l2Ep = optL2Ep.get(); - EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, l2Ep); - if (epFwdCtxOrds == null) { - LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", l2Ep); - return null; - } - - NetworkDomainId epNetworkContainment = getEPNetworkContainment(l2Ep); - - MacAddress epDestMac = l2Ep.getMacAddress(); - MacAddress destSubnetGatewayMac = l2Ep.getMacAddress(); - L3Context destL3c = getL3ContextForSubnet(prefixEp.getTenant(), subnet); - if (destL3c == null || destL3c.getId() == null) { - LOG.error("No L3 Context found associated with subnet {}", subnet.getId()); - return null; - } - - MacAddress matcherMac = routerPortMac(destL3c, subnet.getVirtualRouterIp()); - - ArrayList l3instructions = new ArrayList<>(); - List applyActions = new ArrayList<>(); - List l3ApplyActions = new ArrayList<>(); - - int order = 0; - - Action setdEPG = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(epFwdCtxOrds.getEpgId())); - Action setdCG = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(epFwdCtxOrds.getCgId())); - Action setNextHop; - String nextHop=null; - - OfOverlayContext ofc = l2Ep.getAugmentation(OfOverlayContext.class); - - long portNum = -1; - if (EndpointManager.isInternal(l2Ep, ctx.getTenant(l2Ep.getTenant()).getExternalImplicitGroups())) { - checkNotNull(ofc.getNodeConnectorId()); - nextHop = ofc.getNodeConnectorId().getValue(); - try { - portNum = getOfPortNum(ofc.getNodeConnectorId()); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), ex); - return null; - } - - } else { - // External - Set externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); - checkNotNull(externalPorts); - for (NodeConnectorId externalPort : externalPorts) { - // TODO Bug #3440 Target: Be - should support for more than first external port. - //TODO Bug 3546 - Difficult: External port is unrelated to Tenant, L3C, L2BD.. - nextHop = externalPort.getValue(); - try { - portNum = getOfPortNum(externalPort); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), ex); - return null; + @VisibleForTesting + void syncL3PrefixFlow(DestinationMapperFlows flows, Collection l3Prefixes, + TenantId tenantId, NodeId nodeId, OfWriter ofWriter) { + short policyEnforcerTableId = ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(); + for (EndpointL3Prefix l3Prefix : l3Prefixes) { + List localSubnets = utils.getLocalSubnets(nodeId); + if (localSubnets != null) { + for (Subnet localSubnet : localSubnets) { + for (EndpointL3Gateways l3Gateway : l3Prefix.getEndpointL3Gateways()) { + if (l3Gateway != null && l3Gateway.getL3Context() != null && l3Gateway.getIpAddress() != null) { + EndpointL3 endpointL3 = ctx.getEndpointManager().getL3Endpoint(l3Gateway.getL3Context(), + l3Gateway.getIpAddress(), tenantId); + Endpoint endpointL2 = ctx.getEndpointManager().getL2EndpointFromL3(endpointL3); + IndexedTenant tenant = ctx.getTenant(l3Prefix.getTenant()); + Set externalPorts = ctx.getSwitchManager().getExternalPorts(nodeId); + if (endpointL3 != null && endpointL2 != null && tenant != null && externalPorts != null) { + L3Context l3Context = utils.getL3ContextForSubnet(tenant, localSubnet); + if (l3Context == null || l3Context.getId() == null) { + LOG.error("No L3 Context found associated with subnet {}", localSubnet.getId()); + continue; + } + EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpointL2); + if (ordinals == null) { + LOG.error("No Fwd Ctx ordinals found in endpoint ", endpointL2); + continue; + } + flows.createL3PrefixFlow(policyEnforcerTableId, L3_PREFIX, endpointL2, l3Prefix, tenant, + localSubnet, externalPorts, ofWriter); + } + } + } } - continue; } } - - if (Strings.isNullOrEmpty(nextHop) - || portNum == -1) { - LOG.error("createL3Prefix - Cannot find nodeConnectorId for {} for Prefix: ", l2Ep, prefixEp); - return null; - } - setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(portNum)); - - Action setDlDst = setDlDstAction(epDestMac); - l3ApplyActions.add(setDlDst); - - Action decTtl = decNwTtlAction(); - l3ApplyActions.add(decTtl); - - order += 1; - applyActions.add(setdEPG); - applyActions.add(setdCG); - applyActions.add(setNextHop); - - applyActions.addAll(l3ApplyActions); - Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - - l3instructions.add(applyActionsIns); - Instruction gotoTable = new InstructionBuilder().setOrder(order++) - .setInstruction(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())) - .build(); - l3instructions.add(gotoTable); - - Layer3Match m = null; - Long etherType = null; - String ikey = null; - Integer prefixLength=0; - if (prefixEp.getIpPrefix().getIpv4Prefix() != null) { - ikey = prefixEp.getIpPrefix().getIpv4Prefix().getValue(); - etherType = IPv4; - prefixLength=Integer.valueOf(prefixEp.getIpPrefix().getIpv4Prefix().getValue().split("/")[1]); - m = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build(); - } else if (prefixEp.getIpPrefix().getIpv6Prefix() != null) { - ikey = prefixEp.getIpPrefix().getIpv6Prefix().getValue(); - etherType = IPv6; - /* - * This will result in flows with priority between 100-228, but since its matching on IPv6 prefix as well - * this shouldn't pose and issue, as the priority is more important within the address space of the matcher, - * even though technically flows are processed in priority order. - */ - - prefixLength=Integer.valueOf(prefixEp.getIpPrefix().getIpv6Prefix().getValue().split("/")[1]); - m = new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ikey)).build(); - } else { - LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.", prefixEp); - return null; - } - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)); - addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(epFwdCtxOrds.getL3Id()))); - Match match = mb.build(); - FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "L3prefix", match); - FlowBuilder flowb = base().setId(flowid) - .setPriority(Integer.valueOf(BASE_L3_PRIORITY+prefixLength)) - .setMatch(match) - .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); - return flowb.build(); - } - - private Flow createBroadcastFlow(EndpointFwdCtxOrdinals epOrd) { - MatchBuilder mb = new MatchBuilder() - .setEthernetMatch(new EthernetMatchBuilder().setEthernetDestination( - new EthernetDestinationBuilder().setAddress(MULTICAST_MAC) - .setMask(MULTICAST_MAC) - .build()).build()); - addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(epOrd.getFdId()))); - - Match match = mb.build(); - FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "broadcast", match); - FlowBuilder flowb = base().setPriority(Integer.valueOf(140)) - .setId(flowId) - .setMatch(match) - .setInstructions( - instructions(applyActionIns(nxLoadTunIdAction(BigInteger.valueOf(epOrd.getFdId()), false), - groupAction(Long.valueOf(epOrd.getFdId()))))); - - return flowb.build(); } - private MacAddress routerPortMac(L3Context l3c, IpAddress ipAddress) { - - if (ctx.getDataBroker() == null) { - return null; + private void syncExternalFlows(DestinationMapperFlows flows, Endpoint endpoint, Endpoint peerEndpoint, + Endpoint gatewayEndpoint, Set externalPorts, OfWriter ofWriter) { + EndpointFwdCtxOrdinals peerOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEndpoint); + if (peerOrdinals == null) { + return; } - - MacAddress defaultMacAddress = ROUTER_MAC; - - EndpointL3Key l3Key = new EndpointL3Key(ipAddress, l3c.getId()); - InstanceIdentifier endpointsIid = InstanceIdentifier.builder(Endpoints.class) - .child(EndpointL3.class, l3Key) - .build(); - ReadOnlyTransaction t = ctx.getDataBroker().newReadOnlyTransaction(); - - Optional r; - try { - r = t.read(LogicalDatastoreType.OPERATIONAL, endpointsIid).get(); - if (!r.isPresent()) - return defaultMacAddress; - EndpointL3 epL3 = r.get(); - if (epL3.getMacAddress() == null) { - return defaultMacAddress; - } else { - return epL3.getMacAddress(); + short goToTable = ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(); + if (endpoint.getNetworkContainment().equals(peerEndpoint.getNetworkContainment())) { + if (externalPorts.iterator().hasNext()) { + // L2 flow + flows.createExternalL2Flow(goToTable, EXTERNAL_L2, peerEndpoint, externalPorts, ofWriter); } - } catch (Exception e) { - LOG.error("Error reading EndpointL3 {}.{}", l3c, ipAddress, e); - return null; - } - } - - private L3Context getL3ContextForSubnet(TenantId tenantId, Subnet sn) { - IndexedTenant indexedTenant = ctx.getTenant(tenantId); - if (indexedTenant == null) { - LOG.debug("Tenant {} is null, cannot get L3 context", tenantId); - return null; - } - L3Context l3c = indexedTenant.resolveL3Context(sn.getId()); - return l3c; - } - - private Flow createRouterArpFlow(TenantId tenantId, NodeId nodeId, Subnet sn, int l3Id) { - if (sn == null || sn.getVirtualRouterIp() == null) { - LOG.trace("Didn't create routerArpFlow since either subnet or subnet virtual router was null"); - return null; - } - /* - * TODO: Li alagalah: This should be new Yang "gateways" list as well, - * that expresses the gateway and prefixes it is interface for. Should - * also check for external. - */ - if (sn.getVirtualRouterIp().getIpv4Address() != null) { - String ikey = sn.getVirtualRouterIp().getIpv4Address().getValue(); - - L3Context l3c = getL3ContextForSubnet(tenantId, sn); - if (l3c == null) { - LOG.error("No L3 Context found associated with subnet {}", sn.getId()); + } else if (gatewayEndpoint != null) { + HashSet subnets = utils.getSubnets(peerEndpoint.getTenant()); + if (subnets == null) { + LOG.trace("No subnets in tenant {}", peerEndpoint.getTenant()); + return; } - - MacAddress routerMac = routerPortMac(l3c, sn.getVirtualRouterIp()); - if (routerMac == null) { - return null; + for (L3Address l3Address : endpoint.getL3Address()) { + if (l3Address.getIpAddress() == null || l3Address.getL3Context() == null) { + LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}", + endpoint.getL3Address()); + continue; + } + // L3 flow + flows.createExternalL3RoutedFlow(goToTable, L3_EXTERNAL, peerEndpoint, gatewayEndpoint, l3Address, + externalPorts, ofWriter); } - - BigInteger intRouterMac = new BigInteger(1, bytesFromHexString(routerMac.getValue())); - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP)).setLayer3Match( - new ArpMatchBuilder().setArpOp(Integer.valueOf(1)) - .setArpTargetTransportAddress(new Ipv4Prefix(ikey + "/32")) - .build()); - addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(l3Id))); - - Match match = mb.build(); - FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "routerarp", match); - FlowBuilder flowb = base().setPriority(150) - .setId(flowId) - .setMatch(match) - .setInstructions( - instructions(applyActionIns(nxMoveEthSrcToEthDstAction(), setDlSrcAction(routerMac), - nxLoadArpOpAction(BigInteger.valueOf(2L)), nxMoveArpShaToArpThaAction(), - nxLoadArpShaAction(intRouterMac), nxMoveArpSpaToArpTpaAction(), - nxLoadArpSpaAction(ikey), outputAction(new NodeConnectorId(nodeId.getValue() - + ":INPORT"))))); - return flowb.build(); - } else { - LOG.warn("IPv6 virtual router {} for subnet {} not supported", sn.getVirtualRouterIp(), sn.getId() - .getValue()); - return null; - } - - } - - private Flow createLocalL2Flow(Endpoint ep, EndpointFwdCtxOrdinals epFwdCtxOrds, OfOverlayContext ofc) { - - // TODO Li alagalah - refactor common code but keep simple method - ArrayList instructions = new ArrayList<>(); - List applyActions = new ArrayList<>(); - - int order = 0; - - Action setdEPG = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(epFwdCtxOrds.getEpgId())); - Action setdCG = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(epFwdCtxOrds.getCgId())); - Action setNextHop; - String nextHop; - - // BEGIN L2 LOCAL - nextHop = ofc.getNodeConnectorId().getValue(); - - long portNum; - try { - portNum = getOfPortNum(ofc.getNodeConnectorId()); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), ex); - return null; } - - setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(portNum)); - - // END L2 LOCAL - - order += 1; - applyActions.add(setdEPG); - applyActions.add(setdCG); - applyActions.add(setNextHop); - Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - instructions.add(applyActionsIns); - - Instruction gotoTable = new InstructionBuilder().setOrder(order++) - .setInstruction(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())) - .build(); - instructions.add(gotoTable); - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, ep.getMacAddress(), null)); - addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(epFwdCtxOrds.getBdId()))); - Match match = mb.build(); - FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "localL2", match); - FlowBuilder flowb = base().setId(flowid) - .setPriority(Integer.valueOf(50)) - .setMatch(match) - .setInstructions(new InstructionsBuilder().setInstruction(instructions).build()); - return flowb.build(); } - private void syncEP(OfWriter ofWriter, NodeId nodeId, Endpoint srcEp, Endpoint destEp) - throws Exception { - - if (ctx.getTenant(srcEp.getTenant()) == null - || ctx.getTenant(destEp.getTenant()) == null) { - LOG.debug("Source or destination EP references empty tenant srcEp:{} destEp:{}", srcEp, destEp); - return; - } - - // TODO: Conditions messed up, but for now, send policyInfo until this - // is fixed. - EndpointFwdCtxOrdinals destEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, destEp); - if (destEpFwdCtxOrds == null) { - LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", destEp); - return; - } - EndpointFwdCtxOrdinals srcEpFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, srcEp); - if (srcEpFwdCtxOrds == null) { - LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", srcEp); + private void syncLocalFlows(DestinationMapperFlows flows, Endpoint endpoint, List localSubnets, + OfWriter ofWriter) { + short goToTable = ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(); + // L2 Flow + flows.createLocalL2Flow(goToTable, LOCAL_L2, endpoint, ofWriter); + if (endpoint.getL3Address() == null) { + LOG.trace("Endpoint {} didn't have L3 Address so was not processed for L3 flows.", endpoint.getKey()); return; } - - - if (destEp.getTenant() == null || (destEp.getEndpointGroup() == null && destEp.getEndpointGroups() == null)) { - if (destEp.getTenant() == null) { - LOG.debug("Didn't process endpoint {} due to tenant being null", destEp.getKey()); + for (L3Address l3Address : endpoint.getL3Address()) { + if (l3Address.getIpAddress() == null || l3Address.getL3Context() == null) { + LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}", + endpoint.getL3Address()); } else { - LOG.debug("Didn't process endpoint {} due to EPG(s) being null", destEp.getKey()); - } - return; - } - - /* - * Only care about subnets for L3, but fetch them before loop. We need - * the local subnets for setting SRC MAC for routing. All Routing is now - * done locally! YAY! Instead of being shovelled L2 style across network - * ala Helium. - */ - List localSubnets = getLocalSubnets(nodeId); - if (localSubnets == null) { - LOG.error("No subnets could be found locally for node: {}", nodeId); - return; - } - - OfOverlayContext ofc = destEp.getAugmentation(OfOverlayContext.class); - - // forwarding outside of internal domain should be done when dest EP or GW is external. - Subnet srcSubnet = ctx.getTenant(srcEp.getTenant()).resolveSubnet(new SubnetId(srcEp.getNetworkContainment())); - Endpoint l2Gw = this.getL2EndpointOfSubnetGateway(srcEp.getTenant(), srcSubnet); - boolean destEpIsExternal = destEp.getNetworkContainment() != null - && EndpointManager.isExternal(destEp, ctx.getTenant(destEp.getTenant()).getExternalImplicitGroups()); - boolean subnetGwIsExternal = l2Gw != null - && EndpointManager.isExternal(l2Gw, ctx.getTenant(l2Gw.getTenant()).getExternalImplicitGroups()); - if (destEpIsExternal || subnetGwIsExternal) { - if (ofc == null && destEp.getNetworkContainment().equals(srcEp.getNetworkContainment())) { - Flow flow = createExternalL2Flow(destEp, destEpFwdCtxOrds, nodeId); - if (flow != null) { - ofWriter.writeFlow(nodeId, TABLE_ID, flow); - } - } else if (l2Gw != null && EndpointManager.isExternal(l2Gw, ctx.getTenant(l2Gw.getTenant()).getExternalImplicitGroups()) - && !destEp.getNetworkContainment().equals(srcEp.getNetworkContainment())) { - for (L3Address l3a : destEp.getL3Address()) { - if (l3a.getIpAddress() == null || l3a.getL3Context() == null) { - LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}", - destEp.getL3Address()); + for (Subnet localSubnet : localSubnets) { + HashSet subnets = utils.getSubnets(endpoint.getTenant()); + if (subnets == null) { + LOG.trace("No subnets in tenant {}", utils.getIndexedTenant(endpoint.getTenant())); continue; } - for (Subnet localSubnet : localSubnets) { - Flow extL3Flow = createExternalL3RoutedFlow(destEp, l3a, destEpFwdCtxOrds, localSubnet, nodeId); - if (extL3Flow != null) { - ofWriter.writeFlow(nodeId, TABLE_ID, extL3Flow); - } else { - LOG.trace("Did not write remote L3 flow for endpoint {} and subnet {}", l3a.getIpAddress(), - localSubnet.getIpPrefix().getValue()); - } + Subnet remoteSubnet = ctx.getTenant(endpoint.getTenant()) + .resolveSubnet(new SubnetId(endpoint.getNetworkContainment())); + // Do check + if(checked(localSubnet, remoteSubnet, l3Address, endpoint)) { + // L3 flow + flows.createLocalL3RoutedFlow(goToTable, L3_LOCAL, endpoint, l3Address, localSubnet, remoteSubnet, + ofWriter); } } } } - else if (ofc != null && Objects.equals(ofc.getNodeId(), nodeId)) { - // this is a local endpoint; send to the approppriate local - // port - - if (srcEpFwdCtxOrds.getBdId() == destEpFwdCtxOrds.getBdId()) { - ofWriter.writeFlow(nodeId, TABLE_ID, createLocalL2Flow(destEp, destEpFwdCtxOrds, ofc)); - } - // TODO Li alagalah: Need to move to EndpointL3 for L3 processing. - // The Endpoint conflation must end! - if (destEp.getL3Address() == null) { - LOG.trace("Endpoint {} didn't have L3 Address so was not processed for L3 flows.", destEp.getKey()); - return; - } - - for (L3Address l3a : destEp.getL3Address()) { - if (l3a.getIpAddress() == null || l3a.getL3Context() == null) { - LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}", - destEp.getL3Address()); - continue; - } else { - for (Subnet localSubnet : localSubnets) { - Flow flow = createLocalL3RoutedFlow(destEp, l3a, destEpFwdCtxOrds, ofc, localSubnet); - if (flow != null) { - ofWriter.writeFlow(nodeId, TABLE_ID, flow); - } else { - LOG.trace("Did not write remote L3 flow for endpoint {} and subnet {}", l3a.getIpAddress(), - localSubnet.getIpPrefix().getValue()); - } - } - } - } - } else if(ofc!= null) { - // this endpoint is on a different switch; send to the - // appropriate tunnel - if (srcEpFwdCtxOrds.getBdId() == destEpFwdCtxOrds.getBdId()) { - Flow remoteL2Flow = createRemoteL2Flow(destEp, nodeId, srcEpFwdCtxOrds, destEpFwdCtxOrds, ofc); - if (remoteL2Flow != null) { - ofWriter.writeFlow(nodeId, TABLE_ID, remoteL2Flow); - } - } else { - LOG.trace("DestinationMapper: RemoteL2Flow: not created, in different BDs src: {} dst: {}", - srcEpFwdCtxOrds.getBdId(), destEpFwdCtxOrds.getBdId()); - } - - // TODO Li alagalah: Need to move to EndpointL3 for L3 processing. - // The Endpoint conflation must end! - if (destEp.getL3Address() == null) { - LOG.trace("Endpoint {} didn't have L3 Address so was not processed for L3 flows.", destEp.getKey()); - return; - } - for (L3Address l3a : destEp.getL3Address()) { - if (l3a.getIpAddress() == null || l3a.getL3Context() == null) { - LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}", - destEp.getL3Address()); - continue; - } else { - for (Subnet localSubnet : localSubnets) { - Flow remoteL3Flow = createRemoteL3RoutedFlow(destEp, l3a, nodeId, srcEpFwdCtxOrds, - destEpFwdCtxOrds, ofc, localSubnet); - if (remoteL3Flow != null) { - ofWriter.writeFlow(nodeId, TABLE_ID, remoteL3Flow); - } else { - LOG.trace("Did not write remote L3 flow for endpoint {} and subnet {}", l3a.getIpAddress(), - localSubnet.getIpPrefix().getValue()); - } - } - } - } - } // remote (tunnel) - - // } - } - /* - * ################################## DestMapper Flow methods - * ################################## - */ - private Flow createLocalL3RoutedFlow(Endpoint destEp, L3Address destL3Address, EndpointFwdCtxOrdinals epFwdCtxOrds, - OfOverlayContext ofc, Subnet srcSubnet) { - - // TODO Li alagalah - refactor common code but keep simple method - - Subnet destSubnet = null; - HashSet subnets = getSubnets(destEp.getTenant()); - if (subnets == null) { - LOG.trace("No subnets in tenant {}", destEp.getTenant()); - return null; - } - NetworkDomainId epNetworkContainment = getEPNetworkContainment(destEp); - for (Subnet subnet : subnets) { - // TODO Li alagalah add IPv6 support - if (subnet.getId().getValue().equals(epNetworkContainment.getValue())) { - destSubnet = subnet; - break; + private void syncRemoteFlows(DestinationMapperFlows flows, Endpoint endpoint, Endpoint peerEndpoint, OfOverlayContext ofc, + NodeId nodeId, EndpointFwdCtxOrdinals endpointOrdinals, + EndpointFwdCtxOrdinals peerOrdinals, List localSubnets, OfWriter ofWriter) { + short goToTable = ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(); + if (endpointOrdinals.getBdId() == peerOrdinals.getBdId()) { + IpAddress tunDst = ctx.getSwitchManager().getTunnelIP(ofc.getNodeId(), TunnelTypeVxlan.class); + NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class); + // L2 flow + if (tunDst != null && tunPort != null) { + flows.createRemoteL2Flow(goToTable, REMOTE_L2, endpoint, peerEndpoint, tunDst, tunPort, ofWriter); } - } - if (destSubnet == null) { - LOG.trace("Destination IP address does not match any subnet in tenant {}", destL3Address.getIpAddress()); - return null; - } - - if (destSubnet.getVirtualRouterIp() == null) { - LOG.trace("Destination subnet {} for Endpoint {}.{} has no gateway IP", destSubnet.getIpPrefix(), - destL3Address.getKey()); - return null; - } - - if (srcSubnet.getVirtualRouterIp() == null) { - LOG.trace("Local subnet {} has no gateway IP", srcSubnet.getIpPrefix()); - return null; - } - L3Context destL3c = getL3ContextForSubnet(destEp.getTenant(), destSubnet); - if (destL3c == null || destL3c.getId() == null) { - LOG.error("No L3 Context found associated with subnet {}", destSubnet.getId()); - return null; - } - L3Context srcL3c = getL3ContextForSubnet(destEp.getTenant(), srcSubnet); - if (srcL3c == null || srcL3c.getId() == null) { - LOG.error("No L3 Context found associated with subnet {}", srcSubnet.getId()); - return null; - } - - if (!(srcL3c.getId().getValue().equals(destL3c.getId().getValue()))) { - LOG.trace("Trying to route between two L3Contexts {} and {}. Not currently supported.", srcL3c.getId() - .getValue(), destL3c.getId().getValue()); - return null; - } - - MacAddress matcherMac = routerPortMac(destL3c, srcSubnet.getVirtualRouterIp()); - MacAddress epDestMac = destEp.getMacAddress(); - MacAddress destSubnetGatewayMac = routerPortMac(destL3c, destSubnet.getVirtualRouterIp()); - - if (srcSubnet.getId().getValue().equals(destSubnet.getId().getValue())) { - // This is our final destination, so match on actual EP mac. - matcherMac = epDestMac; - } - - ArrayList l3instructions = new ArrayList<>(); - List applyActions = new ArrayList<>(); - List l3ApplyActions = new ArrayList<>(); - - int order = 0; - - Action setdEPG = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(epFwdCtxOrds.getEpgId())); - Action setdCG = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(epFwdCtxOrds.getCgId())); - Action setNextHop; - String nextHop; - - // BEGIN L3 LOCAL - nextHop = ofc.getNodeConnectorId().getValue(); - - long portNum; - try { - portNum = getOfPortNum(ofc.getNodeConnectorId()); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), ex); - return null; - } - - setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(portNum)); - // END L3 LOCAL - - // Lets not re-write the srcMac if its local. - if (!(matcherMac.getValue().equals(epDestMac.getValue()))) { - Action setDlSrc = setDlSrcAction(destSubnetGatewayMac); - l3ApplyActions.add(setDlSrc); - } - - Action setDlDst = setDlDstAction(epDestMac); - l3ApplyActions.add(setDlDst); - - Action decTtl = decNwTtlAction(); - l3ApplyActions.add(decTtl); - - order += 1; - applyActions.add(setdEPG); - applyActions.add(setdCG); - applyActions.add(setNextHop); - - applyActions.addAll(l3ApplyActions); - Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - - l3instructions.add(applyActionsIns); - Instruction gotoTable = new InstructionBuilder().setOrder(order++) - .setInstruction(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())) - .build(); - l3instructions.add(gotoTable); - Layer3Match m = null; - Long etherType = null; - String ikey = null; - if (destL3Address.getIpAddress().getIpv4Address() != null) { - ikey = destL3Address.getIpAddress().getIpv4Address().getValue() + "/32"; - etherType = IPv4; - m = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build(); - } else if (destL3Address.getIpAddress().getIpv6Address() != null) { - ikey = destL3Address.getIpAddress().getIpv6Address().getValue() + "/128"; - etherType = IPv6; - m = new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ikey)).build(); } else { - LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.", destL3Address.toString()); - return null; + LOG.trace("DestinationMapper: RemoteL2Flow: not created, in different BDs src: {} dst: {}", + endpointOrdinals.getBdId(), peerOrdinals.getBdId()); } - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)) - .setLayer3Match(m); - addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(epFwdCtxOrds.getL3Id()))); - Match match = mb.build(); - FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "localL3", match); - FlowBuilder flowb = base().setId(flowid) - .setPriority(Integer.valueOf(132)) - .setMatch(match) - .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); - return flowb.build(); - } - - private Flow createExternalL3RoutedFlow(Endpoint destEp, L3Address destL3Address, EndpointFwdCtxOrdinals epFwdCtxOrds, - Subnet srcSubnet, NodeId nodeId) { - - Subnet destSubnet = null; - HashSet subnets = getSubnets(destEp.getTenant()); - if (subnets == null) { - LOG.trace("No subnets in tenant {}", destEp.getTenant()); - return null; - } - NetworkDomainId epNetworkContainment = getEPNetworkContainment(destEp); - for (Subnet subnet : subnets) { - // TODO Li alagalah add IPv6 support - if (subnet.getId().getValue().equals(epNetworkContainment.getValue())) { - destSubnet = subnet; - break; - } - } - if (destSubnet == null) { - LOG.trace("Destination IP address does not match any subnet in tenant {}", destL3Address.getIpAddress()); - return null; - } - - if (destSubnet.getVirtualRouterIp() == null) { - LOG.trace("Destination subnet {} for Endpoint {}.{} has no gateway IP", destSubnet.getIpPrefix(), - destL3Address.getKey()); - return null; - } - - if (srcSubnet.getVirtualRouterIp() == null) { - LOG.trace("Local subnet {} has no gateway IP", srcSubnet.getIpPrefix()); - return null; - } - L3Context destL3c = getL3ContextForSubnet(destEp.getTenant(), destSubnet); - if (destL3c == null || destL3c.getId() == null) { - LOG.error("No L3 Context found associated with subnet {}", destSubnet.getId()); - return null; - } - L3Context srcL3c = getL3ContextForSubnet(destEp.getTenant(), srcSubnet); - if (srcL3c == null || srcL3c.getId() == null) { - LOG.error("No L3 Context found associated with subnet {}", srcSubnet.getId()); - return null; - } - - if (!(srcL3c.getId().getValue().equals(destL3c.getId().getValue()))) { - LOG.trace("Trying to route between two L3Contexts {} and {}. Not currently supported.", srcL3c.getId() - .getValue(), destL3c.getId().getValue()); - return null; - } - - Endpoint l2Gw = getL2EndpointOfSubnetGateway(destEp.getTenant(), srcSubnet); - if(l2Gw == null) { - LOG.warn("The endpoint representing external gateway of subnet {} not found", srcSubnet); - return null; - } - MacAddress matcherMac = destEp.getMacAddress(); - MacAddress destSubnetGatewayMac = l2Gw.getMacAddress(); - - ArrayList l3instructions = new ArrayList<>(); - List applyActions = new ArrayList<>(); - List l3ApplyActions = new ArrayList<>(); - - int order = 0; - - Action setdEPG = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(epFwdCtxOrds.getEpgId())); - Action setdCG = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(epFwdCtxOrds.getCgId())); - Action setNextHop; - - Set extPorts = ctx.getSwitchManager().getExternalPorts(nodeId); - if (extPorts == null || !extPorts.iterator().hasNext()) { - LOG.warn("No external interface on node: {}. External Gateway {} is not reachable!", nodeId, l2Gw.getKey()); - return null; - } - // only one external port is supported for now - NodeConnectorId extPort = extPorts.iterator().next(); - - long portNum; - try { - portNum = getOfPortNum(extPort); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", extPort, ex); - return null; - } - - setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(portNum)); - // END L3 LOCAL - - - Action setDlSrc = setDlSrcAction(destSubnetGatewayMac); - l3ApplyActions.add(setDlSrc); - - Action setDlDst = setDlDstAction(l2Gw.getMacAddress()); - l3ApplyActions.add(setDlDst); - - order += 1; - applyActions.add(setdEPG); - applyActions.add(setdCG); - applyActions.add(setNextHop); - - applyActions.addAll(l3ApplyActions); - Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - - l3instructions.add(applyActionsIns); - Instruction gotoTable = new InstructionBuilder().setOrder(order++) - .setInstruction(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())) - .build(); - l3instructions.add(gotoTable); - Layer3Match m = null; - Long etherType = null; - String ikey = null; - if (destL3Address.getIpAddress().getIpv4Address() != null) { - ikey = destL3Address.getIpAddress().getIpv4Address().getValue() + "/32"; - etherType = IPv4; - m = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build(); - } else if (destL3Address.getIpAddress().getIpv6Address() != null) { - ikey = destL3Address.getIpAddress().getIpv6Address().getValue() + "/128"; - etherType = IPv6; - m = new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ikey)).build(); - } else { - LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.", destL3Address.toString()); - return null; + if (peerEndpoint.getL3Address() == null) { + LOG.trace("Endpoint {} didn't have L3 Address so was not processed for L3 flows.", peerEndpoint.getKey()); + return; } - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)) - .setLayer3Match(m); - addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(epFwdCtxOrds.getL3Id()))); - Match match = mb.build(); - FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "externalL3", match); - FlowBuilder flowb = base().setId(flowid) - .setPriority(Integer.valueOf(132)) - .setMatch(match) - .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); - return flowb.build(); - } - - private Endpoint getL2EndpointOfSubnetGateway(TenantId tenantId, Subnet subnet) { - if (subnet != null && subnet.getVirtualRouterIp() != null) { - IpAddress gwIpAddress = subnet.getVirtualRouterIp(); - Collection prefixEps = ctx.getEndpointManager().getEndpointsL3PrefixForTenant(tenantId); - if (prefixEps != null) { - for (EndpointL3Prefix prefixEp : prefixEps) { - for (EndpointL3Gateways gw : prefixEp.getEndpointL3Gateways()) { - EndpointL3 l3Ep = ctx.getEndpointManager().getL3Endpoint(gw.getL3Context(), gwIpAddress, - prefixEp.getTenant()); - if (l3Ep != null && l3Ep.getL2Context() != null && l3Ep.getMacAddress() != null) { - return ctx.getEndpointManager().getEndpoint( - new EpKey(l3Ep.getL2Context(), l3Ep.getMacAddress())); + for (L3Address l3Address : peerEndpoint.getL3Address()) { + if (l3Address.getIpAddress() == null || l3Address.getL3Context() == null) { + LOG.error("Endpoint with L3Address but either IPAddress or L3Context is null. {}", + peerEndpoint.getL3Address()); + } else { + for (Subnet localSubnet : localSubnets) { + HashSet subnets = utils.getSubnets(peerEndpoint.getTenant()); + if (subnets == null) { + LOG.trace("No subnets in tenant {}", peerEndpoint.getTenant()); + return; + } + Subnet remoteSubnet = ctx.getTenant(peerEndpoint.getTenant()) + .resolveSubnet(new SubnetId(peerEndpoint.getNetworkContainment())); + // Do check + if(checked(localSubnet, remoteSubnet, l3Address, peerEndpoint)) { + IpAddress tunDst = ctx.getSwitchManager().getTunnelIP(ofc.getNodeId(), TunnelTypeVxlan.class); + NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class); + // L3 flow + if (tunDst != null && tunPort != null) { + flows.createRemoteL3RoutedFlow(goToTable, REMOTE_L3, peerEndpoint, l3Address, remoteSubnet, tunDst, + tunPort, localSubnet, ofWriter); } } } } } - return null; } - private Flow createRemoteL2Flow(Endpoint ep, NodeId nodeId, EndpointFwdCtxOrdinals srcEpFwdCtxOrds, - EndpointFwdCtxOrdinals destEpFwdCtxOrds, OfOverlayContext ofc) { - - // TODO Li alagalah - refactor common code but keep simple method - - // this endpoint is on a different switch; send to the - // appropriate tunnel - - ArrayList instructions = new ArrayList<>(); - List applyActions = new ArrayList<>(); - - int order = 0; - - Action setdEPG = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(destEpFwdCtxOrds.getEpgId())); - Action setdCG = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(destEpFwdCtxOrds.getCgId())); - Action setNextHop; - String nextHop; - - // BEGIN TUNNEL HANDLING - IpAddress tunDst = ctx.getSwitchManager().getTunnelIP(ofc.getNodeId(), TunnelTypeVxlan.class); - NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class); - if (tunDst == null) { - LOG.warn("Failed to get Tunnel IP for NodeId {} with EP {}", nodeId, ep); - return null; - } - if (tunPort == null) { - LOG.warn("Failed to get Tunnel Port for NodeId {} with EP {}", nodeId, ep); - return null; - } - - Action tundstAction; - - if (tunDst.getIpv4Address() != null) { - nextHop = tunDst.getIpv4Address().getValue(); - tundstAction = nxLoadTunIPv4Action(nextHop, false); - } else if (tunDst.getIpv6Address() != null) { - // nextHop = tunDst.getIpv6Address().getValue(); - LOG.error("IPv6 tunnel destination {} for {} not supported", tunDst.getIpv6Address().getValue(), - ofc.getNodeId()); - return null; - } else { - // this shouldn't happen - LOG.error("Tunnel IP for {} invalid", ofc.getNodeId()); - return null; - } - - long portNum; - try { - portNum = getOfPortNum(tunPort); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), ex); - return null; - } - - setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(portNum)); - applyActions.add(tundstAction); - // END TUNNEL - - order += 1; - applyActions.add(setdEPG); - applyActions.add(setdCG); - applyActions.add(setNextHop); - Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - instructions.add(applyActionsIns); - - applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - - Instruction gotoTable = new InstructionBuilder().setOrder(order++) - .setInstruction(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())) - .build(); - instructions.add(gotoTable); - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, ep.getMacAddress(), null)); - addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(destEpFwdCtxOrds.getBdId()))); - Match match = mb.build(); - FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "remoteL2", match); - FlowBuilder flowb = base().setId(flowid) - .setPriority(Integer.valueOf(50)) - .setMatch(match) - .setInstructions(new InstructionsBuilder().setInstruction(instructions).build()); - - return flowb.build(); - } - - private Flow createExternalL2Flow(Endpoint ep, EndpointFwdCtxOrdinals epFwdCtxOrds,NodeId nodeId) { - - ArrayList instructions = new ArrayList<>(); - List applyActions = new ArrayList<>(); - - int order = 0; - - Action setdEPG = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(epFwdCtxOrds.getEpgId())); - Action setdCG = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(epFwdCtxOrds.getCgId())); - Action setNextHop; - - // BEGIN L2 LOCAL - Set extPorts = ctx.getSwitchManager().getExternalPorts(nodeId); - if(extPorts == null || !extPorts.iterator().hasNext()) { - return null; - } - // Only one external port is currently supported. - NodeConnectorId extPort = extPorts.iterator().next(); - long portNum; - try { - portNum = getOfPortNum(extPort); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", extPort, ex); - return null; + private boolean checked(Subnet localSubnet, Subnet remoteSubnet, L3Address l3Address, Endpoint peerEndpoint) { + if(peerEndpoint.getTenant() == null) { + LOG.trace("Endpoint {} does not contain info about tenant", peerEndpoint.getKey()); + return false; } - setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(portNum)); - - // END L2 LOCAL - - order += 1; - applyActions.add(setdEPG); - applyActions.add(setdCG); - applyActions.add(setNextHop); - Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - instructions.add(applyActionsIns); - - Instruction gotoTable = new InstructionBuilder().setOrder(order++) - .setInstruction(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())) - .build(); - instructions.add(gotoTable); - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, ep.getMacAddress(), null)); - addNxRegMatch(mb, RegMatch.of(NxmNxReg4.class, Long.valueOf(epFwdCtxOrds.getBdId()))); - Match match = mb.build(); - FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "externalL2", match); - FlowBuilder flowb = base().setId(flowid) - .setPriority(Integer.valueOf(50)) - .setMatch(match) - .setInstructions(new InstructionsBuilder().setInstruction(instructions).build()); - return flowb.build(); - } - - private Flow createRemoteL3RoutedFlow(Endpoint destEp, L3Address destL3Address, NodeId nodeId, - EndpointFwdCtxOrdinals srcEpFwdCtxOrds, EndpointFwdCtxOrdinals destEpFwdCtxOrds, OfOverlayContext ofc, - Subnet srcSubnet) { - - // TODO Li alagalah - refactor common code but keep simple method - - // this endpoint is on a different switch; send to the - // appropriate tunnel - Subnet destSubnet = null; - HashSet subnets = getSubnets(destEp.getTenant()); - if (subnets == null) { - LOG.trace("No subnets in tenant {}", destEp.getTenant()); - return null; - } - NetworkDomainId epNetworkContainment = getEPNetworkContainment(destEp); - for (Subnet subnet : subnets) { - // TODO Li alagalah add IPv6 support - if (subnet.getId().getValue().equals(epNetworkContainment.getValue())) { - destSubnet = subnet; - break; - } - } - if (destSubnet == null) { - LOG.info("Destination IP address does not match any subnet in tenant {}", destL3Address.getIpAddress()); - return null; + if (remoteSubnet == null) { + LOG.trace("Destination IP address does not match any subnet in tenant {}", + l3Address.getIpAddress()); + return false; } - - if (destSubnet.getVirtualRouterIp() == null) { - LOG.trace("Destination subnet {} for Endpoint {}.{} has no gateway IP", destSubnet.getIpPrefix(), - destL3Address.getKey()); - return null; + if (remoteSubnet.getVirtualRouterIp() == null) { + LOG.trace("Destination subnet {} for Endpoint {}.{} has no gateway IP", + remoteSubnet.getIpPrefix(), peerEndpoint, l3Address.getKey()); + return false; } - - if (srcSubnet.getVirtualRouterIp() == null) { - LOG.trace("Local subnet {} has no gateway IP", srcSubnet.getIpPrefix()); - return null; + if (localSubnet.getVirtualRouterIp() == null) { + LOG.trace("Local subnet {} has no gateway IP", localSubnet.getIpPrefix()); + return false; } - L3Context destL3c = getL3ContextForSubnet(destEp.getTenant(), destSubnet); + L3Context destL3c = utils.getL3ContextForSubnet(ctx.getTenant(peerEndpoint.getTenant()), remoteSubnet); if (destL3c == null || destL3c.getId() == null) { - LOG.error("No L3 Context found associated with subnet {}", destSubnet.getId()); - return null; + LOG.error("No L3 Context found associated with subnet {}", remoteSubnet.getId()); + return false; } - L3Context srcL3c = getL3ContextForSubnet(destEp.getTenant(), srcSubnet); + L3Context srcL3c = utils.getL3ContextForSubnet(ctx.getTenant(peerEndpoint.getTenant()), localSubnet); if (srcL3c == null || srcL3c.getId() == null) { - LOG.error("No L3 Context found associated with subnet {}", srcSubnet.getId()); - return null; + LOG.error("No L3 Context found associated with subnet {}", localSubnet.getId()); + return false; } - if (!(srcL3c.getId().getValue().equals(destL3c.getId().getValue()))) { LOG.trace("Trying to route between two L3Contexts {} and {}. Not currently supported.", srcL3c.getId() - .getValue(), destL3c.getId().getValue()); - return null; - } - - MacAddress matcherMac = routerPortMac(destL3c, srcSubnet.getVirtualRouterIp()); - MacAddress epDestMac = destEp.getMacAddress(); - MacAddress destSubnetGatewayMac = routerPortMac(destL3c, destSubnet.getVirtualRouterIp()); - if (srcSubnet.getId().getValue().equals(destSubnet.getId().getValue())) { - // This is our final destination, so match on actual EP mac. - matcherMac = epDestMac; - } - ArrayList l3instructions = new ArrayList<>(); - List applyActions = new ArrayList<>(); - List l3ApplyActions = new ArrayList<>(); - - int order = 0; - - Action setdEPG = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(destEpFwdCtxOrds.getEpgId())); - Action setdCG = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(destEpFwdCtxOrds.getCgId())); - Action setNextHop; - String nextHop; - - // BEGIN TUNNEL HANDLING - IpAddress tunDst = ctx.getSwitchManager().getTunnelIP(ofc.getNodeId(), TunnelTypeVxlan.class); - NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(nodeId, TunnelTypeVxlan.class); - if (tunDst == null) { - LOG.warn("Failed to get Tunnel IP for NodeId {} with L3Address {}", nodeId, destL3Address); - return null; - } - if (tunPort == null) { - LOG.warn("Failed to get Tunnel port for NodeId {} with L3Address {}", nodeId, destL3Address); - return null; - } - - Action tundstAction; - - if (tunDst.getIpv4Address() != null) { - nextHop = tunDst.getIpv4Address().getValue(); - tundstAction = nxLoadTunIPv4Action(nextHop, false); - } else if (tunDst.getIpv6Address() != null) { - // nextHop = tunDst.getIpv6Address().getValue(); - LOG.error("IPv6 tunnel destination {} for {} not supported", tunDst.getIpv6Address().getValue(), - ofc.getNodeId()); - return null; - } else { - // this shouldn't happen - LOG.error("Tunnel IP for {} invalid", ofc.getNodeId()); - return null; - } - - long portNum; - try { - portNum = getOfPortNum(tunPort); - } catch (NumberFormatException ex) { - LOG.warn("Could not parse port number {}", ofc.getNodeConnectorId(), ex); - return null; - } - - setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(portNum)); - applyActions.add(tundstAction); - // END TUNNEL - - order += 1; - applyActions.add(setdEPG); - applyActions.add(setdCG); - applyActions.add(setNextHop); - - // Lets not re-write the srcMac if its local. - if (!(matcherMac.getValue().equals(epDestMac.getValue()))) { - Action setDlSrc = setDlSrcAction(destSubnetGatewayMac); - l3ApplyActions.add(setDlSrc); - } - - Action setDlDst = setDlDstAction(epDestMac); - l3ApplyActions.add(setDlDst); - - Action decTtl = decNwTtlAction(); - l3ApplyActions.add(decTtl); - - applyActions.addAll(l3ApplyActions); - Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) - .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) - .build(); - - l3instructions.add(applyActionsIns); - Instruction gotoTable = new InstructionBuilder().setOrder(order++) - .setInstruction(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER())) - .build(); - l3instructions.add(gotoTable); - Layer3Match m = null; - Long etherType = null; - String ikey = null; - if (destL3Address.getIpAddress().getIpv4Address() != null) { - ikey = destL3Address.getIpAddress().getIpv4Address().getValue() + "/32"; - etherType = IPv4; - m = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build(); - } else if (destL3Address.getIpAddress().getIpv6Address() != null) { - ikey = destL3Address.getIpAddress().getIpv6Address().getValue() + "/128"; - etherType = IPv6; - m = new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ikey)).build(); - } else { - LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.", destL3Address.toString()); - return null; - } - - MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)) - .setLayer3Match(m); - addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(destEpFwdCtxOrds.getL3Id()))); - Match match = mb.build(); - FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "remoteL3", match); - FlowBuilder flowb = base().setId(flowid) - .setPriority(Integer.valueOf(132)) - .setMatch(match) - .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); - return flowb.build(); - } - - private NetworkDomainId getEPNetworkContainment(Endpoint endpoint) { - if (endpoint.getNetworkContainment() != null) { - return endpoint.getNetworkContainment(); - } else { - /* - * TODO: Be alagalah: Endpoint Refactor: This should be set on input - * which we can't do because of the backwards way endpoints were - * "architected". - */ - return ctx.getTenant(endpoint.getTenant()) - .getEndpointGroup(endpoint.getEndpointGroup()) - .getNetworkDomain(); - } - } - - private HashSet getSubnets(final TenantId tenantId) { - - if (ctx.getDataBroker() == null) { - return null; - } - - ReadOnlyTransaction t = ctx.getDataBroker().newReadOnlyTransaction(); - InstanceIdentifier tiid = TenantUtils.tenantIid(tenantId); - Optional tenantInfo; - try { - tenantInfo = t.read(LogicalDatastoreType.CONFIGURATION, tiid).get(); - } catch (Exception e) { - LOG.error("Could not read Tenant {}", tenantId, e); - return null; - } finally { - t.close(); - } - - if (!tenantInfo.isPresent()) { - LOG.warn("Tenant {} not found", tenantId); - return null; - } - - ForwardingContext fwCtx = tenantInfo.get().getForwardingContext(); - if (fwCtx == null || fwCtx.getSubnet() == null) { - return new HashSet<>(); - } - return new HashSet<>(fwCtx.getSubnet()); - } - - // Need a method to get subnets for EPs attached to the node locally - // to set the source Mac address for the router interface. - private List getLocalSubnets(NodeId nodeId) { - Collection endpointsForNode = ctx.getEndpointManager().getEndpointsForNode(nodeId); - - List localSubnets = new ArrayList(); - - for (Endpoint endpoint : endpointsForNode) { - HashSet subnets = getSubnets(endpoint.getTenant()); - if (subnets == null) { - LOG.debug("No local subnets in tenant {} for EP {}.", endpoint.getTenant(), endpoint.getKey()); - continue; - } - NetworkDomainId epNetworkContainment = getEPNetworkContainment(endpoint); - for (Subnet subnet : subnets) { - if (epNetworkContainment.getValue().equals(subnet.getId().getValue())) { - localSubnets.add(subnet); - } - } - } - return localSubnets; - } - - public static byte[] bytesFromHexString(String values) { - String target = ""; - if (values != null) { - target = values; - } - String[] octets = target.split(":"); - - byte[] ret = new byte[octets.length]; - for (int i = 0; i < octets.length; i++) { - ret[i] = Integer.valueOf(octets[i], 16).byteValue(); + .getValue(), destL3c.getId().getValue()); + return false; } - return ret; + return true; } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlows.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlows.java new file mode 100644 index 000000000..b7cea0f68 --- /dev/null +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlows.java @@ -0,0 +1,714 @@ +/* + * Copyright (c) 2014 Cisco Systems, 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.groupbasedpolicy.renderer.ofoverlay.mapper.destination; + +import com.google.common.base.Preconditions; +import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +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.InstructionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*; + +class DestinationMapperFlows { + + private static final Logger LOG = LoggerFactory.getLogger(DestinationMapperFlows.class); + private final DestinationMapperUtils utils; + private final NodeId nodeId; + private final short tableId; + + public DestinationMapperFlows(DestinationMapperUtils utils, NodeId nodeId, short tableId) { + this.utils = Preconditions.checkNotNull(utils); + this.nodeId = Preconditions.checkNotNull(nodeId); + this.tableId = tableId; + } + + /** + * Default flow which drops all incoming traffic + * + * @param priority of flow in the table + * @param etherType can be set as specific protocol to match + * @param ofWriter flow writer + */ + void dropFlow(int priority, Long etherType, OfWriter ofWriter) { + FlowId flowId; + FlowBuilder flowBuilder = FlowUtils.base(tableId) + .setPriority(priority) + .setInstructions(FlowUtils.dropInstructions()); + if (etherType != null) { + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType)); + Match match = matchBuilder.build(); + flowId = FlowIdUtils.newFlowId(tableId, "drop", match); + flowBuilder.setMatch(match); + } else { + flowId = FlowIdUtils.newFlowId("dropAll"); + } + flowBuilder.setId(flowId); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + /** + * Create external L2 flow for every external port found on node + * + * @param goToTable {@link GoToTable} instruction value + * @param priority of the flow + * @param peerEndpoint original endpoint (input parameter to {@link DestinationMapper#sync(Endpoint, OfWriter)} + * @param externalPorts list of external {@link NodeConnectorId}-s get from node + * @param ofWriter flow writer + */ + void createExternalL2Flow(short goToTable, int priority, Endpoint peerEndpoint, Set externalPorts, + OfWriter ofWriter) { + OrdinalFactory.EndpointFwdCtxOrdinals peerOrdinals = utils.getEndpointOrdinals(peerEndpoint); + if (peerOrdinals != null) { + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(ethernetMatch(null, peerEndpoint.getMacAddress(), null)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) peerOrdinals.getBdId())); + Match match = matchBuilder.build(); + + long port; + for (NodeConnectorId externalPort : externalPorts) { + try { + port = getOfPortNum(externalPort); + writeExternalL2Flow(goToTable, priority, peerOrdinals, port, match, ofWriter); + } catch (NumberFormatException e) { + LOG.warn("Invalid NodeConnectorId. External port: {}", externalPort); + } + } + } + } + + /** + * Create external L3 flow for every external port found on node + * + * @param goToTable {@link GoToTable} instruction value + * @param priority of the flow + * @param peerEndpoint to original endpoint (input parameter to {@link DestinationMapper#sync(Endpoint, OfWriter)} + * @param l2GatewayEp L2 endpoint of subnet gateway + * @param destL3Address endpoint L3 address + * @param externalPorts list of external {@link NodeConnectorId}-s get from node + * @param ofWriter flow writer + */ + void createExternalL3RoutedFlow(short goToTable, int priority, Endpoint peerEndpoint, Endpoint l2GatewayEp, + L3Address destL3Address, Set externalPorts, OfWriter ofWriter) { + OrdinalFactory.EndpointFwdCtxOrdinals peerOrdinals = utils.getEndpointOrdinals(peerEndpoint); + if (peerOrdinals != null) { + Layer3Match layer3Match; + Long etherType; + String ikey; + if (destL3Address.getIpAddress() != null && destL3Address.getIpAddress().getIpv4Address() != null) { + ikey = destL3Address.getIpAddress().getIpv4Address().getValue() + "/32"; + etherType = IPv4; + layer3Match = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build(); + } else if (destL3Address.getIpAddress() != null && destL3Address.getIpAddress().getIpv6Address() != null) { + ikey = destL3Address.getIpAddress().getIpv6Address().getValue() + "/128"; + etherType = IPv6; + layer3Match = new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ikey)).build(); + } else { + LOG.error("Endpoint has Ip Address that is not recognised as either IPv4 or IPv6.", destL3Address); + return; + } + MacAddress matcherMac = peerEndpoint.getMacAddress(); + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)) + .setLayer3Match(layer3Match); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) peerOrdinals.getL3Id())); + Match match = matchBuilder.build(); + + long port; + for (NodeConnectorId externalPort : externalPorts) { + try { + port = getOfPortNum(externalPort); + writeExternalL3RoutedFlow(goToTable, priority, port, l2GatewayEp, match, peerOrdinals, ofWriter); + } catch (NumberFormatException e) { + LOG.warn("Invalid NodeConnectorId. External port: {}", externalPort); + } + } + } + } + + /** + * Create local L2 flow + * + * @param goToTable {@link GoToTable} instruction value + * @param priority of the flow + * @param endpoint original endpoint (input parameter to {@link DestinationMapper#sync(Endpoint, OfWriter)} + * @param ofWriter flow writer + */ + void createLocalL2Flow(short goToTable, int priority, Endpoint endpoint, OfWriter ofWriter) { + OfOverlayContext context = endpoint.getAugmentation(OfOverlayContext.class); + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpoint); + + Action setNextHop; + try { + setNextHop = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(getOfPortNum(context.getNodeConnectorId()))); + } catch (NumberFormatException ex) { + LOG.warn("Could not parse port number {}", context.getNodeConnectorId(), ex); + return; + } + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(ordinals.getEpgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(ordinals.getCgId()))); + applyActions.add(setNextHop); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(goToTable)) + .build(); + + ArrayList instructions = new ArrayList<>(); + instructions.add(applyActionsIns); + instructions.add(gotoTable); + + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(ethernetMatch(null, endpoint.getMacAddress(), null)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) ordinals.getBdId())); + Match match = matchBuilder.build(); + FlowId flowId = FlowIdUtils.newFlowId(tableId, "localL2", match); + FlowBuilder flowBuilder = base(tableId).setId(flowId) + .setPriority(priority) + .setMatch(match) + .setInstructions(new InstructionsBuilder().setInstruction(instructions).build()); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + /** + * Create local L3 routed flow + * + * @param goToTable {@link GoToTable} instruction value + * @param priority of the flow + * @param endpoint original endpoint (input parameter to {@link DestinationMapper#sync(Endpoint, OfWriter)} + * @param l3Address endpoint L3 address + * @param localSubnet subnet from local node + * @param destSubnet destination endpoint's subnet + * @param ofWriter flow writer + */ + void createLocalL3RoutedFlow(short goToTable, int priority, Endpoint endpoint, L3Address l3Address, + Subnet localSubnet, Subnet destSubnet, OfWriter ofWriter) { + NodeConnectorId connectorId = endpoint.getAugmentation(OfOverlayContext.class).getNodeConnectorId(); + L3Context l3Context = utils.getL3ContextForSubnet(utils.getIndexedTenant(endpoint.getTenant()), localSubnet); + if (l3Context == null) { + return; + } + MacAddress matcherMac = utils.routerPortMac(l3Context, localSubnet.getVirtualRouterIp(), endpoint.getTenant()); + MacAddress epDestMac = endpoint.getMacAddress(); + if (matcherMac == null || epDestMac == null) { + return; + } + MacAddress destSubnetGatewayMac = utils.routerPortMac(l3Context, destSubnet.getVirtualRouterIp(), + endpoint.getTenant()); + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpoint); + if (localSubnet.getId().getValue().equals(destSubnet.getId().getValue())) { + matcherMac = epDestMac; + } + Action setNextHopAction; + try { + setNextHopAction = nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(getOfPortNum(connectorId))); + } catch (NumberFormatException ex) { + LOG.warn("Could not parse port number {}", connectorId, ex); + return; + } + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlDstAction(epDestMac)); + l3ApplyActions.add(decNwTtlAction()); + if (!(matcherMac.getValue().equals(epDestMac.getValue()))) { + l3ApplyActions.add(setDlSrcAction(destSubnetGatewayMac)); + } + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(ordinals.getEpgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(ordinals.getCgId()))); + applyActions.add(setNextHopAction); + applyActions.addAll(l3ApplyActions); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(goToTable)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + Layer3Match l3Match; + Long etherType; + String ikey; + if (l3Address.getIpAddress() != null && l3Address.getIpAddress().getIpv4Address() != null) { + ikey = l3Address.getIpAddress().getIpv4Address().getValue() + "/32"; + etherType = IPv4; + l3Match = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build(); + } else if (l3Address.getIpAddress() != null && l3Address.getIpAddress().getIpv6Address() != null) { + ikey = l3Address.getIpAddress().getIpv6Address().getValue() + "/128"; + etherType = IPv6; + l3Match = new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ikey)).build(); + } else { + LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.", l3Address.toString()); + return; + } + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)) + .setLayer3Match(l3Match); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) ordinals.getL3Id())); + Match match = matchBuilder.build(); + FlowId flowid = FlowIdUtils.newFlowId(tableId, "localL3", match); + FlowBuilder flowBuilder = base(tableId).setId(flowid) + .setPriority(priority) + .setMatch(match) + .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + /** + * Create remote L2 flow + * + * @param goToTable {@link GoToTable} instruction value + * @param priority of the flow + * @param endpoint original peer + * @param peerEndpoint peer endpoint to original endpoint + * @param tunDst tunnel destination Ip address + * @param connectorId tunnel port + * @param ofWriter flow writer + */ + void createRemoteL2Flow(short goToTable, int priority, Endpoint endpoint, Endpoint peerEndpoint, IpAddress tunDst, + NodeConnectorId connectorId, OfWriter ofWriter) { + OrdinalFactory.EndpointFwdCtxOrdinals endpointOrdinals = utils.getEndpointOrdinals(endpoint); + long port; + try { + port = getOfPortNum(connectorId); + } catch (NumberFormatException ex) { + LOG.warn("Could not parse port number {}", connectorId); + return; + } + Action tunnelDestinationAction = null; + if (tunDst.getIpv4Address() != null) { + tunnelDestinationAction = nxLoadTunIPv4Action(tunDst.getIpv4Address().getValue(), false); + } else if (tunDst.getIpv6Address() != null) { + LOG.error("IPv6 tunnel destination {} for {} not supported", tunDst.getIpv6Address().getValue(), + nodeId); + return; + } + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(endpointOrdinals.getEpgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(endpointOrdinals.getCgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(port))); + applyActions.add(tunnelDestinationAction); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(goToTable)) + .build(); + + ArrayList instructions = new ArrayList<>(); + instructions.add(applyActionsIns); + instructions.add(gotoTable); + + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(ethernetMatch(null, peerEndpoint.getMacAddress(), null)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) endpointOrdinals.getBdId())); + Match match = matchBuilder.build(); + FlowId flowid = FlowIdUtils.newFlowId(tableId, "remoteL2", match); + FlowBuilder flowBuilder = base(tableId).setId(flowid) + .setPriority(priority) + .setMatch(match) + .setInstructions(new InstructionsBuilder().setInstruction(instructions).build()); + + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + /** + * Create remote L3 routed flow + * + * @param goToTable {@link GoToTable} instruction value + * @param priority of the flow + * @param endpoint peer + * @param destL3Address destination L3 address + * @param destSubnet subnet from destination node + * @param tunDst tunnel destination Ip address + * @param connectorId tunnel port + * @param localSubnet subnet from local node + * @param ofWriter flow writer + */ + void createRemoteL3RoutedFlow(short goToTable, int priority, Endpoint endpoint, L3Address destL3Address, + Subnet destSubnet, IpAddress tunDst, NodeConnectorId connectorId, Subnet localSubnet, + OfWriter ofWriter) { + L3Context context = utils.getL3ContextForSubnet(utils.getIndexedTenant(endpoint.getTenant()), destSubnet); + if (context == null) { + return; + } + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpoint); + MacAddress matcherMac = utils.routerPortMac(context, localSubnet.getVirtualRouterIp(), endpoint.getTenant()); + MacAddress epDestMac = endpoint.getMacAddress(); + if (matcherMac == null || epDestMac == null) { + return; + } + MacAddress destSubnetGatewayMac = utils.routerPortMac(context, destSubnet.getVirtualRouterIp(), + endpoint.getTenant()); + + // L3 Actions + List l3ApplyActions = new ArrayList<>(); + if (localSubnet.getId().getValue().equals(destSubnet.getId().getValue())) { + // This is our final destination, so match on actual EP mac. + matcherMac = epDestMac; + } + if (!(matcherMac.getValue().equals(epDestMac.getValue()))) { + Action setDlSrc = setDlSrcAction(destSubnetGatewayMac); + l3ApplyActions.add(setDlSrc); + } + l3ApplyActions.add(setDlDstAction(epDestMac)); + l3ApplyActions.add(decNwTtlAction()); + + + // Actions + Action tunnelDestinationAction; + if (tunDst != null && tunDst.getIpv4Address() != null) { + tunnelDestinationAction = nxLoadTunIPv4Action(tunDst.getIpv4Address().getValue(), false); + } else if (tunDst != null && tunDst.getIpv6Address() != null) { + LOG.error("IPv6 tunnel destination {} for {} not supported", tunDst.getIpv6Address().getValue(), nodeId); + return; + } else { + LOG.error("Tunnel IP for {} invalid", nodeId); + return; + } + long port; + try { + port = getOfPortNum(connectorId); + } catch (NumberFormatException ex) { + LOG.warn("Could not parse port number {}", connectorId, ex); + return; + } + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(ordinals.getEpgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(ordinals.getCgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(port))); + applyActions.add(tunnelDestinationAction); + applyActions.addAll(l3ApplyActions); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(goToTable)) + .build(); + + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + + Layer3Match layer3Match; + Long etherType; + String ikey; + if (destL3Address.getIpAddress().getIpv4Address() != null) { + ikey = destL3Address.getIpAddress().getIpv4Address().getValue() + "/32"; + etherType = IPv4; + layer3Match = new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ikey)).build(); + } else { + ikey = destL3Address.getIpAddress().getIpv6Address().getValue() + "/128"; + etherType = IPv6; + layer3Match = new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ikey)).build(); + } + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMac, etherType)) + .setLayer3Match(layer3Match); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) ordinals.getL3Id())); + Match match = matchBuilder.build(); + FlowId flowid = FlowIdUtils.newFlowId(tableId, "remoteL3", match); + FlowBuilder flowBuilder = base(tableId).setId(flowid) + .setPriority(priority) + .setMatch(match) + .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + /** + * Creates arp flow using virtual router IP in {@link Subnet} + * + * @param priority of the flow + * @param indexedTenant of the {@link Endpoint} + * @param subnet entries get from peer's tenants + * @param ofWriter flow writer + * @throws Exception could be thrown during {@link OrdinalFactory#getContextOrdinal(TenantId, UniqueId)}. Handled + * in {@link DestinationMapper#syncArpFlow(DestinationMapperFlows, TenantId, OfWriter)} + */ + void createRouterArpFlow(int priority, IndexedTenant indexedTenant, Subnet subnet, OfWriter ofWriter) + throws Exception { + Tenant tenant = indexedTenant.getTenant(); + if (tenant != null) { + L3Context l3Context = utils.getL3ContextForSubnet(indexedTenant, subnet); + if (l3Context != null) { + int contextOrdinal = OrdinalFactory.getContextOrdinal(tenant.getId(), l3Context.getId()); + MacAddress routerMac = utils.routerPortMac(l3Context, subnet.getVirtualRouterIp(), + indexedTenant.getTenant().getId()); + if (routerMac != null) { + if (subnet.getVirtualRouterIp().getIpv4Address() == null + && subnet.getVirtualRouterIp().getIpv6Address() != null) { + LOG.warn("IPv6 virtual router {} for subnet {} not supported", subnet.getVirtualRouterIp(), subnet.getId() + .getValue()); + return; + } + String ipv4Value = subnet.getVirtualRouterIp().getIpv4Address().getValue(); + BigInteger intRouterMac = new BigInteger(1, bytesFromHexString(routerMac.getValue())); + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(ethernetMatch(null, null, ARP)) + .setLayer3Match(new ArpMatchBuilder() + .setArpOp(1) + .setArpTargetTransportAddress(new Ipv4Prefix(ipv4Value + "/32")) + .build()); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) contextOrdinal)); + Match match = matchBuilder.build(); + FlowId flowId = FlowIdUtils.newFlowId(tableId, "routerarp", match); + FlowBuilder flowBuilder = base(tableId).setPriority(priority) + .setId(flowId) + .setMatch(match) + .setInstructions(instructions(applyActionIns(nxMoveEthSrcToEthDstAction(), + setDlSrcAction(routerMac), nxLoadArpOpAction(BigInteger.valueOf(2L)), + nxMoveArpShaToArpThaAction(), nxLoadArpShaAction(intRouterMac), + nxMoveArpSpaToArpTpaAction(), nxLoadArpSpaAction(ipv4Value), + outputAction(new NodeConnectorId(nodeId.getValue() + ":INPORT"))))); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + } else { + LOG.error("No L3 Context found associated with subnet {}.", subnet.getId()); + } + } + } + + /** + * Broadcast flow for destination mapper + * + * @param priority of the flow + * @param ordinals of the endpoint (input parameter in {@link DestinationMapper#sync(Endpoint, OfWriter)}) + * @param mac address of the multicast router {@link DestinationMapper#MULTICAST_MAC} + * @param ofWriter flow writer + */ + void createBroadcastFlow(int priority, OrdinalFactory.EndpointFwdCtxOrdinals ordinals, MacAddress mac, + OfWriter ofWriter) { + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(new EthernetMatchBuilder() + .setEthernetDestination(new EthernetDestinationBuilder().setAddress(mac).setMask(mac).build()) + .build()); + addNxRegMatch(matchBuilder, FlowUtils.RegMatch.of(NxmNxReg5.class, (long) ordinals.getFdId())); + Match match = matchBuilder.build(); + FlowId flowId = FlowIdUtils.newFlowId(tableId, "broadcast", match); + FlowBuilder flowBuilder = base(tableId) + .setPriority(priority) + .setId(flowId) + .setMatch(match) + .setInstructions(instructions(applyActionIns(nxLoadTunIdAction(BigInteger + .valueOf(ordinals.getFdId()), false), groupAction((long) ordinals.getFdId())))); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + /** + * L3 prefix flow is created with endpoint {@link NodeConnectorId} if internal. If endpoint is external and + * external ports are present, one flow per external port is created + * + * @param goToTable policy enforcer table Id + * @param priority of the flow + * @param gatewayEp L2 endpoint, should contain {@link MacAddress} and {@link OrdinalFactory.EndpointFwdCtxOrdinals} + * @param l3Prefix endpoint L3 prefix value + * @param tenant value get from {@link L3Prefix} + * @param localSubnet value where this node is present + * @param externalPorts list of all external ports + * @param ofWriter flow writer + */ + void createL3PrefixFlow(short goToTable, int priority, Endpoint gatewayEp, EndpointL3Prefix l3Prefix, IndexedTenant tenant, + Subnet localSubnet, Set externalPorts, OfWriter ofWriter) { + L3Context l3Context = utils.getL3ContextForSubnet(tenant, localSubnet); + if (l3Context != null && localSubnet.getVirtualRouterIp() != null) { + MacAddress matcherMacAddress = utils.routerPortMac(l3Context, localSubnet.getVirtualRouterIp(), + tenant.getTenant().getId()); + OfOverlayContext context = gatewayEp.getAugmentation(OfOverlayContext.class); + if (EndpointManager.isInternal(gatewayEp, tenant.getExternalImplicitGroups())) { + Preconditions.checkNotNull(context.getNodeConnectorId()); + try { + Long port = getOfPortNum(context.getNodeConnectorId()); + if(matcherMacAddress != null) { + writeL3PrefixFlow(priority, goToTable, gatewayEp, l3Prefix, port, matcherMacAddress, ofWriter); + } + } catch (NumberFormatException e) { + LOG.warn("Could not parse port number {}", context.getNodeConnectorId()); + } + } else { // External + for (NodeConnectorId externalPort : externalPorts) { + try { + Long port = getOfPortNum(externalPort); + if(matcherMacAddress != null) { + writeL3PrefixFlow(priority, goToTable, gatewayEp, l3Prefix, port, matcherMacAddress, ofWriter); + } + } catch (NumberFormatException e) { + LOG.warn("Could not parse port number {}", externalPort); + } + } + } + } + } + + private void writeExternalL2Flow(short goToTable, int priority, OrdinalFactory.EndpointFwdCtxOrdinals ordinals, + Long port, Match match, OfWriter ofWriter) { + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(ordinals.getEpgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(ordinals.getCgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(port))); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(goToTable)) + .build(); + + ArrayList instructions = new ArrayList<>(); + instructions.add(applyActionsIns); + instructions.add(gotoTable); + + FlowId flowId = FlowIdUtils.newFlowId(tableId, "externalL2", match); + FlowBuilder flowBuilder = base(tableId).setId(flowId) + .setPriority(priority) + .setMatch(match) + .setInstructions(new InstructionsBuilder().setInstruction(instructions).build()); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + private void writeExternalL3RoutedFlow(short goToTable, int priority, long port, Endpoint l2GatewayEp, Match match, + OrdinalFactory.EndpointFwdCtxOrdinals peerOrdinals, OfWriter ofWriter) { + MacAddress destSubnetGatewayMac = l2GatewayEp.getMacAddress(); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlSrcAction(destSubnetGatewayMac)); + l3ApplyActions.add(setDlDstAction(l2GatewayEp.getMacAddress())); + + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(peerOrdinals.getEpgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(peerOrdinals.getCgId()))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(port))); + applyActions.addAll(l3ApplyActions); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(goToTable)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + + FlowId flowid = FlowIdUtils.newFlowId(tableId, "externalL3", match); + FlowBuilder flowBuilder = base(tableId).setId(flowid) + .setPriority(priority) + .setMatch(match) + .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + + private void writeL3PrefixFlow(int priority, short goToTable, Endpoint endpoint, EndpointL3Prefix l3Prefix, + Long port, MacAddress matcherMacAddress, OfWriter ofWriter) { + MacAddress macAddress = endpoint.getMacAddress(); + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpoint); + Action setEpgAction = nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(ordinals.getEpgId())); + Action setCgAction = nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(ordinals.getCgId())); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlDstAction(macAddress)); + l3ApplyActions.add(decNwTtlAction()); + List applyActions = new ArrayList<>(); + applyActions.add(setEpgAction); + applyActions.add(setCgAction); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(port))); + applyActions.addAll(l3ApplyActions); + + int order = 0; + ArrayList l3instructions = new ArrayList<>(); + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(goToTable)) + .build(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + + if(l3Prefix.getIpPrefix() != null) { + Long etherType; + Integer prefixLength; + if (l3Prefix.getIpPrefix().getIpv4Prefix() != null) { + etherType = IPv4; + prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv4Prefix().getValue().split("/")[1]); + } else if (l3Prefix.getIpPrefix().getIpv6Prefix() != null) { + etherType = IPv6; + prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv6Prefix().getValue().split("/")[1]); + } else { + LOG.error("Endpoint has IPAddress that is not recognised as either IPv4 or IPv6.", l3Prefix); + return; + } + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, matcherMacAddress, etherType)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) ordinals.getL3Id())); + Match match = matchBuilder.build(); + + FlowId flowid = FlowIdUtils.newFlowId(tableId, "L3prefix", match); + FlowBuilder flowBuilder = base(tableId).setId(flowid) + .setPriority(priority + prefixLength) + .setMatch(match) + .setInstructions(new InstructionsBuilder().setInstruction(l3instructions).build()); + ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); + } + } +} diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtils.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtils.java new file mode 100644 index 000000000..48487603b --- /dev/null +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtils.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2014 Cisco Systems, 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.groupbasedpolicy.renderer.ofoverlay.mapper.destination; + + +import com.google.common.base.Preconditions; +import org.opendaylight.groupbasedpolicy.dto.EpKey; +import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class DestinationMapperUtils { + + private static final Logger LOG = LoggerFactory.getLogger(DestinationMapperUtils.class); + + private final OfContext ctx; + + DestinationMapperUtils(OfContext ctx) { + this.ctx = Preconditions.checkNotNull(ctx); + } + + HashSet getSubnets(TenantId tenantId) { + IndexedTenant indexedTenant = ctx.getTenant(tenantId); + if (indexedTenant != null && indexedTenant.getTenant() != null) { + ForwardingContext forwardingContext = indexedTenant.getTenant().getForwardingContext(); + if (forwardingContext != null && forwardingContext.getSubnet() != null) { + return new HashSet<>(forwardingContext.getSubnet()); + } + } + + return new HashSet<>(); + } + + L3Context getL3ContextForSubnet(IndexedTenant indexedTenant, Subnet subnet) { + if (indexedTenant == null) { + return null; + } + return indexedTenant.resolveL3Context(subnet.getId()); + } + + NetworkDomainId getEPNetworkContainment(Endpoint endpoint, IndexedTenant tenant) { + if (endpoint.getNetworkContainment() != null) { + return endpoint.getNetworkContainment(); + } else if (tenant != null) { + return tenant.getEndpointGroup(endpoint.getEndpointGroup()) + .getNetworkDomain(); + } else { + return null; + } + } + + // Need a method to get subnets for EPs attached to the node locally + // to set the source Mac address for the router interface. + List getLocalSubnets(NodeId nodeId) { + Collection endpointsForNode = ctx.getEndpointManager().getEndpointsForNode(nodeId); + + List localSubnets = new ArrayList<>(); + + for (Endpoint endpoint : endpointsForNode) { + HashSet subnets = getSubnets(endpoint.getTenant()); + if (subnets.isEmpty()) { + LOG.debug("No local subnets in tenant {} for EP {}.", endpoint.getTenant(), endpoint.getKey()); + continue; + } + NetworkDomainId epNetworkContainment = getEPNetworkContainment(endpoint, ctx.getTenant(endpoint.getTenant())); + for (Subnet subnet : subnets) { + if (epNetworkContainment.getValue().equals(subnet.getId().getValue())) { + localSubnets.add(subnet); + } + } + } + return localSubnets; + } + + Endpoint getL2EpOfSubnetGateway(TenantId tenantId, Subnet subnet) { + if (subnet != null && subnet.getVirtualRouterIp() != null) { + IpAddress gwIpAddress = subnet.getVirtualRouterIp(); + Collection prefixEps = ctx.getEndpointManager().getEndpointsL3PrefixForTenant(tenantId); + if (prefixEps != null) { + for (EndpointL3Prefix prefixEp : prefixEps) { + for (EndpointL3Gateways gw : prefixEp.getEndpointL3Gateways()) { + EndpointL3 l3Ep = ctx.getEndpointManager().getL3Endpoint(gw.getL3Context(), gwIpAddress, + prefixEp.getTenant()); + if (l3Ep != null && l3Ep.getL2Context() != null && l3Ep.getMacAddress() != null) { + return ctx.getEndpointManager().getEndpoint( + new EpKey(l3Ep.getL2Context(), l3Ep.getMacAddress())); + } + } + } + } + } + return null; + } + + MacAddress routerPortMac(L3Context l3c, IpAddress ipAddress, TenantId tenantId) { + MacAddress defaultMacAddress = DestinationMapper.ROUTER_MAC; + if (l3c.getId() != null) { + EndpointL3 endpointL3 = ctx.getEndpointManager().getL3Endpoint(l3c.getId(), ipAddress, tenantId); + if (endpointL3 == null || endpointL3.getMacAddress() == null) { + return defaultMacAddress; + } else { + return endpointL3.getMacAddress(); + } + } else { + return defaultMacAddress; + } + } + + IndexedTenant getIndexedTenant(TenantId tenantId) { + return ctx.getTenant(tenantId); + } + + Set getAllEndpointGroups(Endpoint endpoint) { + Set groupIds = new HashSet<>(); + if (endpoint.getEndpointGroup() != null) { + groupIds.add(endpoint.getEndpointGroup()); + } + if (endpoint.getEndpointGroups() != null) { + groupIds.addAll(endpoint.getEndpointGroups()); + } + return groupIds; + } + + OrdinalFactory.EndpointFwdCtxOrdinals getEndpointOrdinals(Endpoint endpoint) { + try { + return OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); + } catch (Exception e) { + LOG.error("Failed to get fwd ctx ordinals for endpoint {}", endpoint); + return null; + } + } + +} diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapper.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapper.java index 95384d212..d75afa2e2 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapper.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapper.java @@ -187,19 +187,19 @@ public class ExternalMapper extends FlowTable { // we only use NAT when going to external networks. Ipv4Prefix natIp = new Ipv4Prefix(ipv4Address.getValue() + "/32"); Match match = new MatchBuilder() - .setEthernetMatch(FlowUtils.ethernetMatch(null, null, Long.valueOf(FlowUtils.IPv4))) - .setLayer3Match(new Ipv4MatchBuilder().setIpv4Source(natIp).build()) - .setVlanMatch(FlowUtils.vlanMatch(0, false)) - .build(); + .setEthernetMatch(FlowUtils.ethernetMatch(null, null, Long.valueOf(FlowUtils.IPv4))) + .setLayer3Match(new Ipv4MatchBuilder().setIpv4Source(natIp).build()) + .setVlanMatch(FlowUtils.vlanMatch(0, false)) + .build(); List pushVlanActions = new ArrayList<>(); pushVlanActions.addAll(FlowUtils.pushVlanActions(vlanId)); pushVlanActions.add(new ActionBuilder().setOrder(0).setAction(nxOutputRegAction(NxmNxReg7.class))); FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "external_nat_push_vlan", match); return base().setPriority(priority) - .setId(flowid) - .setMatch(match) - .setInstructions(FlowUtils.instructions(applyActionIns(pushVlanActions))) - .build(); + .setId(flowid) + .setMatch(match) + .setInstructions(FlowUtils.instructions(applyActionIns(pushVlanActions))) + .build(); } public static Subnet resolveSubnetForIpv4Address(IndexedTenant t, Ipv4Address ipv4Addr) { @@ -246,10 +246,10 @@ public class ExternalMapper extends FlowTable { pushVlanActions.add(new ActionBuilder().setOrder(0).setAction(nxOutputRegAction(NxmNxReg7.class))); FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "external_push_vlan", match); flows.add(base().setPriority(priority) - .setId(flowid) - .setMatch(match) - .setInstructions(FlowUtils.instructions(applyActionIns(pushVlanActions))) - .build()); + .setId(flowid) + .setMatch(match) + .setInstructions(FlowUtils.instructions(applyActionIns(pushVlanActions))) + .build()); } return flows; } @@ -257,9 +257,9 @@ public class ExternalMapper extends FlowTable { private Flow defaultFlow() { FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "defaultExternalFlow", null); Flow flow = base().setPriority(100) - .setId(flowid) - .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class)))) - .build(); + .setId(flowid) + .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class)))) + .build(); return flow; } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapper.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapper.java index 3792f412b..0186c2f76 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapper.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapper.java @@ -139,7 +139,7 @@ public class IngressNatMapper extends FlowTable { // Flows for ingress NAT translation Collection l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat(); - OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals = getEndpointOrdinals(endpoint); + OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); EndpointKey endpointKey = endpoint.getKey(); for (EndpointL3 l3Endpoint : l3Endpoints) { L2BridgeDomainId l2Context = l3Endpoint.getL2Context(); @@ -174,18 +174,4 @@ public class IngressNatMapper extends FlowTable { } } } - - private OrdinalFactory.EndpointFwdCtxOrdinals getEndpointOrdinals(Endpoint endpoint) { - try { - OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); - if (ordinals == null) { - LOG.info("getEndpointFwdCtxOrdinals is null for EP {}", endpoint); - return null; - } - return ordinals; - } catch (Exception e) { - LOG.error("Failed to get endpoint ordinals, endpoint: {}", endpoint); - return null; - } - } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlows.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlows.java index 4cf70f99f..1bbc8cd98 100644 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlows.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlows.java @@ -212,7 +212,7 @@ class IngressNatMapperFlows { private Flow createOutsideArpFlow(IndexedTenant tenant, int priority, IpAddress outsideDestAddress, MacAddress toMac, NodeId nodeId) { String ikey = outsideDestAddress.getIpv4Address().getValue(); - BigInteger intMac = new BigInteger(1, bytesFromHexString(toMac.getValue())); + BigInteger intMac = new BigInteger(1, FlowUtils.bytesFromHexString(toMac.getValue())); MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP)).setLayer3Match( new ArpMatchBuilder().setArpOp(1) .setArpTargetTransportAddress(new Ipv4Prefix(ikey + "/32")) @@ -317,18 +317,4 @@ class IngressNatMapperFlows { return null; } } - - private byte[] bytesFromHexString(String values) { - String target = ""; - if (values != null) { - target = values; - } - String[] octets = target.split(":"); - - byte[] ret = new byte[octets.length]; - for (int i = 0; i < octets.length; i++) { - ret[i] = Integer.valueOf(octets[i], 16).byteValue(); - } - return ret; - } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapper.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapper.java index 937c022b4..9d6fc038f 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapper.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapper.java @@ -123,7 +123,8 @@ public class SourceMapper extends FlowTable { for (EgKey peer : peers) { Collection peerEgEndpoints = ctx.getEndpointManager().getEndpointsForGroup(peer); for (Endpoint peerEgEndpoint : peerEgEndpoints) { - OrdinalFactory.EndpointFwdCtxOrdinals ordinals = getEndpointOrdinals(ctx, peerEgEndpoint); + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = + OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, peerEgEndpoint); flows.createTunnelFlow(destinationMapperId, TUNNEL_FLOW, tunnelPort, ordinals, ofWriter); flows.createBroadcastFlow(destinationMapperId, BROADCAST_FLOW, tunnelPort, @@ -138,7 +139,8 @@ public class SourceMapper extends FlowTable { } IndexedTenant tenant = ctx.getTenant(endpoint.getTenant()); // Sync the local EP information - OrdinalFactory.EndpointFwdCtxOrdinals endpointFwdCtxOrdinals = getEndpointOrdinals(ctx, endpoint); + OrdinalFactory.EndpointFwdCtxOrdinals endpointFwdCtxOrdinals = + OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); MacAddress macAddress = endpoint.getMacAddress(); if (endpointFwdCtxOrdinals != null) { OfOverlayContext ofOverlayContext = endpoint.getAugmentation(OfOverlayContext.class); @@ -150,15 +152,6 @@ public class SourceMapper extends FlowTable { } } - private OrdinalFactory.EndpointFwdCtxOrdinals getEndpointOrdinals(OfContext ctx, Endpoint endpoint) { - try { - return OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, endpoint); - } catch (Exception e) { - LOG.error("Failed to get fwd ctx ordinals for endpoint {}", endpoint); - return null; - } - } - private Set getEndpointGroups(Endpoint endpoint) { Set endpointGroups = new HashSet<>(); if (endpoint.getEndpointGroup() != null) { diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java deleted file mode 100755 index 5b9bf9ae9..000000000 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/DestinationMapperTest.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, 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.groupbasedpolicy.renderer.ofoverlay.flow; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.decNwTtlAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.dropInstructions; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.getOfPortNum; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.groupAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpOpAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpShaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadArpSpaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpShaToArpThaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveArpSpaToArpTpaAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveEthSrcToEthDstAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxMoveRegTunIdAction; -import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setDlSrcAction; - -import java.math.BigInteger; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Objects; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.destination.DestinationMapper; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; -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.Flow; -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.list.Instruction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({PolicyManager.class}) -public class DestinationMapperTest extends FlowTableTest { - protected static final Logger LOG = - LoggerFactory.getLogger(DestinationMapperTest.class); - - NodeConnectorId remoteTunnelId = - new NodeConnectorId(remoteNodeId.getValue() + ":101"); - - @Override - @Before - public void setup() throws Exception { - PowerMockito.stub(PowerMockito.method(PolicyManager.class, "setSfcTableOffset")).toReturn(true); - - initCtx(); - table = new DestinationMapper(ctx,ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()); - super.setup(); - } - - @Ignore - @Test - public void testNoEps() throws Exception { - OfWriter fm = dosync(null); - assertEquals(1, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size()); - } - - private void verifyDMap(Endpoint remoteEp, - Endpoint localEp) throws Exception { - - OfWriter fm = dosync(null); - assertNotEquals(0, fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size()); - - // presumably counts flows that have correct matches set up - int count = 0; - HashMap flowMap = new HashMap<>(); - for (Flow f : fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow()) { - flowMap.put(f.getId().getValue(), f); - if (f.getMatch() == null) { - assertEquals(dropInstructions(), - f.getInstructions()); - count += 1; - } else if (Objects.equals(ethernetMatch(null, null, ARP), - f.getMatch().getEthernetMatch())) { - // router ARP reply - Instruction ins = f.getInstructions().getInstruction().get(0); - assertTrue(ins.getInstruction() instanceof ApplyActionsCase); - List actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction(); - assertEquals(nxMoveEthSrcToEthDstAction(), - actions.get(0).getAction()); - assertEquals(Integer.valueOf(0), actions.get(0).getOrder()); - assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC), - actions.get(1).getAction()); - assertEquals(Integer.valueOf(1), actions.get(1).getOrder()); - assertEquals(nxLoadArpOpAction(BigInteger.valueOf(2L)), - actions.get(2).getAction()); - assertEquals(Integer.valueOf(2), actions.get(2).getOrder()); - assertEquals(nxMoveArpShaToArpThaAction(), - actions.get(3).getAction()); - assertEquals(Integer.valueOf(3), actions.get(3).getOrder()); - assertEquals(nxLoadArpShaAction(new BigInteger(1, DestinationMapper - .bytesFromHexString(DestinationMapper.ROUTER_MAC - .getValue()))), - actions.get(4).getAction()); - assertEquals(Integer.valueOf(4), actions.get(4).getOrder()); - assertEquals(nxMoveArpSpaToArpTpaAction(), - actions.get(5).getAction()); - assertEquals(Integer.valueOf(5), actions.get(5).getOrder()); - assertTrue(nxLoadArpSpaAction("10.0.0.1").equals(actions.get(6).getAction()) || - nxLoadArpSpaAction("10.0.1.1").equals(actions.get(6).getAction()) || - nxLoadArpSpaAction("10.0.2.1").equals(actions.get(6).getAction())); - assertEquals(Integer.valueOf(6), actions.get(6).getOrder()); - count += 1; - } else if (Objects.equals(localEp.getMacAddress(), - f.getMatch().getEthernetMatch() - .getEthernetDestination().getAddress())) { - int icount = 0; - for (Instruction ins : f.getInstructions().getInstruction()) { - if (ins.getInstruction() instanceof ApplyActionsCase) { - long p = getOfPortNum(nodeConnectorId); - List actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction(); - assertEquals(nxLoadRegAction(NxmNxReg7.class, - BigInteger.valueOf(p)), - actions.get(2).getAction()); - icount += 1; - } else if (ins.getInstruction() instanceof GoToTableCase) { - assertEquals(gotoTableIns(ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()), - ins.getInstruction()); - icount += 1; - } - } - assertEquals(2, icount); - LOG.info("{}", f); - count += 1; - } else if (Objects.equals(remoteEp.getMacAddress(), - f.getMatch().getEthernetMatch() - .getEthernetDestination().getAddress())) { - int icount = 0; - for (Instruction ins : f.getInstructions().getInstruction()) { - if (ins.getInstruction() instanceof ApplyActionsCase) { - long p = getOfPortNum(tunnelId); - List actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction(); - assertEquals(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(p)), - actions.get(actions.size() - 1).getAction()); - icount += 1; - } else if (ins.getInstruction() instanceof GoToTableCase) { - assertEquals(gotoTableIns((short) (table.getTableId() + 1)), - ins.getInstruction()); - icount += 1; - } - } - assertEquals(2, icount); - LOG.info("{}", f); - count += 1; - } else if (Objects.equals(DestinationMapper.ROUTER_MAC, - f.getMatch().getEthernetMatch() - .getEthernetDestination() - .getAddress())) { - if (f.getMatch().getLayer3Match() instanceof Ipv4Match) { - // should be local port with rewrite dlsrc and dldst plus - // ttl decr - Instruction ins = f.getInstructions().getInstruction().get(0); - assertTrue(ins.getInstruction() instanceof ApplyActionsCase); - List actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction(); - long p = getOfPortNum(nodeConnectorId); - assertEquals(nxLoadRegAction(NxmNxReg7.class, - BigInteger.valueOf(p)), - actions.get(2).getAction()); - assertEquals(Integer.valueOf(2), actions.get(2).getOrder()); - assertEquals(Integer.valueOf(3), actions.get(3).getOrder()); - assertEquals(Integer.valueOf(4), actions.get(4).getOrder()); - assertEquals(decNwTtlAction(), - actions.get(5).getAction()); - assertEquals(Integer.valueOf(5), actions.get(5).getOrder()); - count += 1; - } else if (f.getMatch().getLayer3Match() instanceof Ipv6Match) { - // should be remote port with rewrite dlsrc plus - // ttl decr - Instruction ins = f.getInstructions().getInstruction().get(0); - assertTrue(ins.getInstruction() instanceof ApplyActionsCase); - List actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction(); - long p = getOfPortNum(tunnelId); - assertEquals(nxLoadRegAction(NxmNxReg7.class, - BigInteger.valueOf(p)), - actions.get(4).getAction()); - assertEquals(Integer.valueOf(4), actions.get(4).getOrder()); - assertEquals(setDlSrcAction(DestinationMapper.ROUTER_MAC), - actions.get(5).getAction()); - assertEquals(Integer.valueOf(5), actions.get(5).getOrder()); - assertEquals(decNwTtlAction(), - actions.get(6).getAction()); - assertEquals(Integer.valueOf(6), actions.get(6).getOrder()); - count += 1; - } - } else if (Objects.equals(DestinationMapper.MULTICAST_MAC, - f.getMatch().getEthernetMatch() - .getEthernetDestination() - .getAddress())) { - // broadcast/multicast flow should output to group table - Instruction ins = f.getInstructions().getInstruction().get(0); - assertTrue(ins.getInstruction() instanceof ApplyActionsCase); - List actions = ((ApplyActionsCase) ins.getInstruction()).getApplyActions().getAction(); - assertEquals(nxMoveRegTunIdAction(NxmNxReg0.class, false), - actions.get(0).getAction()); - assertEquals(Integer.valueOf(0), actions.get(0).getOrder()); - - Long v = (long) OrdinalFactory.getContextOrdinal(tid, fd); - assertEquals(groupAction(v), actions.get(1).getAction()); - assertEquals(Integer.valueOf(1), actions.get(1).getOrder()); - count += 1; - } - } - - // TODO Li alagalah: Due to subnet checking this test is no longer setup - // correct. Must address before Li. - // assertEquals(8, count); - assertEquals(fm.getTableForNode(nodeId, ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER()).getFlow().size(), count); - int numberOfFlows = fm.getTableForNode(nodeId, (short) 2).getFlow().size(); - fm = dosync(flowMap); - assertEquals(numberOfFlows, fm.getTableForNode(nodeId, (short) 2).getFlow().size()); - } - - @Override - protected EndpointBuilder localEP() { - return super.localEP() - .setL3Address(ImmutableList.of(new L3AddressBuilder() - .setL3Context(l3c) - .setIpAddress(new IpAddress(new Ipv4Address("10.0.0.1"))) - .build())); - } - - @Override - protected EndpointBuilder remoteEP(NodeId remoteNodeId) { - return super.remoteEP(remoteNodeId) - .setL3Address(ImmutableList.of(new L3AddressBuilder() - .setL3Context(l3c) - .setIpAddress(new IpAddress(new Ipv6Address("::ffff:0:0:0:10.0.0.2"))) - .build())); - } - - private void addSwitches() { - switchManager.addSwitch( - nodeId, - tunnelId, - Collections.emptySet(), - new OfOverlayNodeConfigBuilder().setTunnel( - ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.4"))) - .setTunnelType(TunnelTypeVxlan.class) - .setNodeConnectorId(tunnelId) - .build())).build()); - switchManager.addSwitch( - remoteNodeId, - remoteTunnelId, - Collections.emptySet(), - new OfOverlayNodeConfigBuilder().setTunnel( - ImmutableList.of(new TunnelBuilder().setIp(new IpAddress(new Ipv4Address("1.2.3.5"))) - .setTunnelType(TunnelTypeVxlan.class) - .setNodeConnectorId(tunnelId) - .build())).build()); - } - - @Ignore - @Test - public void testSame() throws Exception { - addSwitches(); - Endpoint localEp = localEP().build(); - endpointManager.addEndpoint(localEp); - Endpoint remoteEp = remoteEP(remoteNodeId).build(); - endpointManager.addEndpoint(remoteEp); - - - ctx.addTenant(baseTenant().setPolicy(new PolicyBuilder(baseTenant().getPolicy()).setContract( - ImmutableList.of(baseContract(null).build())).build()).build()); - verifyDMap(remoteEp, localEp); - } - - @Ignore - @Test - public void testDiff() throws Exception { - addSwitches(); - Endpoint localEp = localEP().build(); - endpointManager.addEndpoint(localEp); - Endpoint remoteEp = remoteEP(remoteNodeId) - .setEndpointGroup(eg2) - .build(); - endpointManager.addEndpoint(remoteEp); - - ctx.addTenant(baseTenant().setPolicy(new PolicyBuilder(baseTenant().getPolicy()).setContract( - ImmutableList.of(baseContract(null).build())).build()).build()); - verifyDMap(remoteEp, localEp); - } - -} diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTableTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTableTest.java index efb4160cd..fd9ee41c3 100755 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTableTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/FlowTableTest.java @@ -36,7 +36,7 @@ public class FlowTableTest extends OfTableTest { } } } - //table.sync(nodeId, ofWriter); + //table.sync(NODE_ID, ofWriter); return ofWriter; } } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/GroupTableTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/GroupTableTest.java index b2cca0761..8fe25913b 100755 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/GroupTableTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/GroupTableTest.java @@ -160,9 +160,9 @@ public class GroupTableTest { @Ignore @Test public void updateTest() throws Exception { - //doNothing().when(groupTable).sync(nodeId, ofWriter); + //doNothing().when(groupTable).sync(NODE_ID, ofWriter); - //groupTable.sync(nodeId, ofWriter); + //groupTable.sync(NODE_ID, ofWriter); //verify(groupTable).sync(any(NodeId.class), any(OfWriter.class)); } @@ -171,7 +171,7 @@ public class GroupTableTest { public void updateTestNoFCN() throws Exception { doReturn(null).when(groupTable).getFCNodeFromDatastore(any(NodeId.class)); - //groupTable.sync(nodeId, ofWriter); + //groupTable.sync(NODE_ID, ofWriter); verify(ofWriter, never()).writeBucket(any(NodeId.class), any(GroupId.class), any(Bucket.class));; verify(ofWriter, never()).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class)); verify(ofWriter, never()).writeGroup(any(NodeId.class), any(GroupId.class), any(GroupTypes.class), @@ -185,7 +185,7 @@ public class GroupTableTest { when(endpointManager.getGroupsForNode(any(NodeId.class))).thenReturn( Collections.emptySet()); - //groupTable.sync(nodeId, ofWriter); + //groupTable.sync(NODE_ID, ofWriter); verify(ofWriter).writeGroup(any(NodeId.class), any(GroupId.class)); } @@ -196,7 +196,7 @@ public class GroupTableTest { when(endpointManager.getGroupsForNode(any(NodeId.class))).thenReturn( Collections.emptySet()); - //groupTable.sync(nodeId, ofWriter); + //groupTable.sync(NODE_ID, ofWriter); verify(ofWriter, never()).writeGroup(any(NodeId.class), any(GroupId.class)); } } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/MapperUtilsTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/MapperUtilsTest.java index 93ac285cb..f49ebcc22 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/MapperUtilsTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/MapperUtilsTest.java @@ -1,5 +1,6 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition; import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; @@ -25,6 +26,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.I import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId; @@ -49,8 +51,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContextBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder; @@ -70,39 +75,43 @@ import java.util.List; public abstract class MapperUtilsTest { - protected static final String IPV4_1 = "170.0.0.1"; - protected static final String IPV4_2 = "190.0.0.1"; - protected static final String MAC_0 = "00:00:00:00:00:00"; - protected static final String MAC_1 = "00:00:00:00:00:01"; - protected static final String CONNECTOR_0 = "0"; - protected static final String CONNECTOR_1 = "1"; + protected static final MacAddress MAC_0 = new MacAddress("00:00:00:00:00:00"); + protected static final MacAddress MAC_1 = new MacAddress("00:00:00:00:00:01"); + protected static final MacAddress MAC_2 = new MacAddress("00:00:00:00:00:02"); + protected static final Ipv4Address IPV4_0 = new Ipv4Address("170.0.0.1"); + protected static final Ipv4Address IPV4_1 = new Ipv4Address("190.0.0.1"); + protected static final Ipv4Address IPV4_2 = new Ipv4Address("210.0.0.1"); + protected static final Ipv6Address IPV6_1 = new Ipv6Address("2000:db80:85a3:08ba:0947:8a2e:3a70:7334"); + protected static final Ipv6Address IPV6_2 = new Ipv6Address("0947:db80:3a70:7334:85a3:8a2e:2000:08ba"); + protected static final NodeConnectorId CONNECTOR_0 = new NodeConnectorId("0"); + protected static final NodeConnectorId CONNECTOR_1 = new NodeConnectorId("1"); + protected static final NodeConnectorId CONNECTOR_2 = new NodeConnectorId("2"); + protected static final SubnetId SUBNET_0 = new SubnetId("subnet0"); + protected static final SubnetId SUBNET_1 = new SubnetId("subnet1"); + protected static final SubnetId SUBNET_2 = new SubnetId("subnet2"); + protected static final SubnetId SUBNET_EXT = new SubnetId("externalSubnet"); protected static final String IP_PREFIX_32 = "/32"; protected static final String IP_PREFIX_128 = "/128"; - protected static final String IPV6_1 = "2000:db80:85a3:08ba:0947:8a2e:3a70:7334"; - protected static final String IPV6_2 = "0947:db80:3a70:7334:85a3:8a2e:2000:08ba"; - protected static final String DHCP_IP = "255.255.255.255"; - protected static final String TENANT_ID = "dummy tenant"; - protected static final String NODE_ID = "dummy node"; + protected static final TenantId TENANT_ID = new TenantId("tenantId"); + protected static final NodeId NODE_ID = new NodeId("nodeId"); + protected static final EndpointGroupId ENDPOINT_GROUP_0 = new EndpointGroupId("eg0"); + protected static final EndpointGroupId ENDPOINT_GROUP_1 = new EndpointGroupId("eg1"); + protected static final EndpointGroupId ENDPOINT_GROUP_2 = new EndpointGroupId("eg2"); + protected static final NetworkDomainId NET_DOMAIN_ID = new NetworkDomainId("ndId"); + protected static final L2BridgeDomainId L2BD_ID = new L2BridgeDomainId("l2bdId"); + protected static final L2FloodDomainId L2FD_ID = new L2FloodDomainId("l2fdId"); + protected static final L2FloodDomainId L2_FD_ID_EXT = new L2FloodDomainId("externalL2fdId"); + protected static final L3ContextId L3C_ID = new L3ContextId("l3cId"); + protected static final ContractId CONTRACT_ID = new ContractId("contractId"); + protected static final ContextId CONTEXT_ID = new L3ContextId("ctxId"); + // Often used strings + protected static final String ALLOW = "allow"; protected static final String L2 = "L2"; - protected static final String EPG_ID = "dummy epg id"; - protected static final String ENDPOINT_GROUP_0 = "eg0"; - protected static final String ENDPOINT_GROUP_1 = "eg1"; - protected static final String ENDPOINT_GROUP_2 = "eg2"; - private static final String DOMAIN_ID = "dummy id"; - protected final NodeId nodeId = new NodeId(NODE_ID); - protected final NodeConnectorId nodeConnectorId = new NodeConnectorId(nodeId.getValue() + CONNECTOR_0); - protected final L2BridgeDomainId bd = new L2BridgeDomainId("c95182ba-7807-43f8-98f7-6c7c720b7639"); - protected final EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12"); - protected final EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276"); - protected final ContractId cid = new ContractId("a5874893-bcd5-46de-96af-3c8d99bedf9f"); - protected final L3ContextId l3c = new L3ContextId("2cf51ee4-e996-467e-a277-2d380334a91d"); - protected final L2FloodDomainId fd = new L2FloodDomainId("98e1439e-52d2-46f8-bd69-5136e6088771"); - protected final L2FloodDomainId ext_fd = new L2FloodDomainId("d8024f7a-b83e-11e5-9912-ba0be0483c18"); - protected final SubnetId sub = new SubnetId("4fcf8dfc-53b5-4aef-84d3-6b5586992fcb"); - protected final SubnetId sub2 = new SubnetId("c285a59f-fcb8-42e6-bf29-87ea522fd626"); - protected final SubnetId sub3 = new SubnetId("a0380d52-2a25-48ef-882c-a4d4cd9e00ec"); - protected final SubnetId ext_sub = new SubnetId("8da17ad9-3261-4dc9-bcff-928a2f73cce7"); - protected final TenantId tid = new TenantId(TENANT_ID); + protected static final String OPENFLOW = "openflow:"; + protected static final String DROP_ALL = "dropAll"; + protected static final String DROP = "drop"; + protected static final String TCP_SRC = "tcp_src_80"; + // Mock variables protected Short tableId; protected OfContext ctx; protected OfWriter ofWriter; @@ -112,143 +121,182 @@ public abstract class MapperUtilsTest { protected PolicyInfo policyInfo; protected FlowTable table; - protected FlowBuilder flowBuilder(FlowId flowId, short tableId, Integer priority, Match match, Instructions instructions) { + protected FlowBuilder buildFlow(FlowId flowId, short tableId, Integer priority, Match match, Instructions instructions) { FlowBuilder flowBuilder = FlowUtils.base(tableId); flowBuilder.setId(flowId) .setPriority(priority) .setMatch(match) .setInstructions(instructions); - return flowBuilder; } - protected EndpointL3Builder endpointL3Builder(String ip, String insideIp, String mac, String l2, boolean ipv6) { + protected EndpointL3Builder buildL3Endpoint(Ipv4Address natIp, Ipv4Address ip, MacAddress mac, String l2bd) { + Preconditions.checkNotNull(natIp); + Preconditions.checkNotNull(ip); + Preconditions.checkNotNull(mac); EndpointL3Builder endpointL3Builder = new EndpointL3Builder(); - - // Set NAT address augmentation - if (ip != null) { - if (ipv6) { - NatAddressBuilder natAddressBuilder = new NatAddressBuilder(); - natAddressBuilder.setNatAddress(new IpAddress(new Ipv6Address(ip))); - endpointL3Builder.addAugmentation(NatAddress.class, natAddressBuilder.build()); - } else { - NatAddressBuilder natAddressBuilder = new NatAddressBuilder(); - natAddressBuilder.setNatAddress(new IpAddress(new Ipv4Address(ip))); - endpointL3Builder.addAugmentation(NatAddress.class, natAddressBuilder.build()); - } - } - - // Set IP address - if (insideIp != null) { - if (ipv6) { - endpointL3Builder.setIpAddress(new IpAddress(new Ipv6Address(insideIp))); - } else { - endpointL3Builder.setIpAddress(new IpAddress(new Ipv4Address(insideIp))); - } + NatAddressBuilder natAddressBuilder = new NatAddressBuilder(); + natAddressBuilder.setNatAddress(new IpAddress(new Ipv4Address(natIp))); + endpointL3Builder.addAugmentation(NatAddress.class, natAddressBuilder.build()); + endpointL3Builder.setIpAddress(new IpAddress(ip)); + endpointL3Builder.setMacAddress(new MacAddress(mac)); + if (l2bd != null) { + endpointL3Builder.setL2Context(new L2BridgeDomainId(l2bd)); } + return endpointL3Builder; + } - // Set MAC - if (mac != null) { - endpointL3Builder.setMacAddress(new MacAddress(mac)); - } + protected EndpointL3Builder buildL3Endpoint(Ipv6Address natIp, Ipv6Address ip, MacAddress mac, String l2bd) { + Preconditions.checkNotNull(natIp); + Preconditions.checkNotNull(ip); + Preconditions.checkNotNull(mac); + EndpointL3Builder endpointL3Builder = new EndpointL3Builder(); + NatAddressBuilder natAddressBuilder = new NatAddressBuilder(); + natAddressBuilder.setNatAddress(new IpAddress(new Ipv6Address(natIp))); + endpointL3Builder.addAugmentation(NatAddress.class, natAddressBuilder.build()); + endpointL3Builder.setIpAddress(new IpAddress(ip)); - // Set L2 context - if (l2 != null) { - endpointL3Builder.setL2Context(new L2BridgeDomainId(l2)); + endpointL3Builder.setMacAddress(new MacAddress(mac)); + if (l2bd != null) { + endpointL3Builder.setL2Context(new L2BridgeDomainId(l2bd)); } - return endpointL3Builder; + } + public SegmentationBuilder buildSegmentation() { + SegmentationBuilder segmentationBuilder = new SegmentationBuilder(); + segmentationBuilder.setSegmentationId(1); + return segmentationBuilder; } - protected IndexedTenant indexedTenantBuilder() { + protected TenantBuilder buildTenant() { TenantBuilder tenantBuilder = new TenantBuilder(); - tenantBuilder.setId(new TenantId(TENANT_ID)); + tenantBuilder.setId(TENANT_ID); + tenantBuilder.setForwardingContext(buildForwardingContext().build()); + PolicyBuilder policyBuilder = new PolicyBuilder(); + policyBuilder.setEndpointGroup(getEndpointGroups()); + policyBuilder.setSubjectFeatureInstances(getSubjectFeatureInstances()); + tenantBuilder.setPolicy(policyBuilder.build()); + return tenantBuilder; + } - // Set forwarding context - SegmentationBuilder segmentationBuilder = new SegmentationBuilder(); - segmentationBuilder.setSegmentationId(1); - List l2FloodDomains = new ArrayList<>(); - L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder(); - l2FloodDomainBuilder.setId(new L2FloodDomainId("l2id")); - l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build()); - l2FloodDomains.add(l2FloodDomainBuilder.build()); + protected IndexedTenant getTestIndexedTenant() { + return new IndexedTenant(buildTenant().build()); + } + + protected ForwardingContextBuilder buildForwardingContext() { ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder(); - forwardingContextBuilder.setL2FloodDomain(l2FloodDomains); - tenantBuilder.setForwardingContext(forwardingContextBuilder.build()); + forwardingContextBuilder.setL2FloodDomain(getL2FloodDomainList(false)); + forwardingContextBuilder.setL2BridgeDomain(getL2BridgeDomainList()); + forwardingContextBuilder.setL3Context(getL3ContextList()); + forwardingContextBuilder.setSubnet(getSubnetList()); + return forwardingContextBuilder; + } - return new IndexedTenant(tenantBuilder.build()); + protected List getL3ContextList() { + List l3Contexts = new ArrayList<>(); + L3ContextBuilder l3ContextBuilder = new L3ContextBuilder(); + l3ContextBuilder.setId(L3C_ID); + l3Contexts.add(l3ContextBuilder.build()); + return l3Contexts; } - protected List l2FloodDomains() { - SegmentationBuilder segmentationBuilder = new SegmentationBuilder(); - segmentationBuilder.setSegmentationId(1); + protected List getL2BridgeDomainList() { + List l2BridgeDomains = new ArrayList<>(); + L2BridgeDomainBuilder l2BridgeDomainBuilder = new L2BridgeDomainBuilder(); + l2BridgeDomainBuilder.setId(L2BD_ID); + l2BridgeDomainBuilder.setParent(L3C_ID); + l2BridgeDomains.add(l2BridgeDomainBuilder.build()); + return l2BridgeDomains; + } + + protected List getL2FloodDomainList(boolean external) { List l2FloodDomains = new ArrayList<>(); L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder(); - l2FloodDomainBuilder.setId(new L2FloodDomainId("l2id")); - l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build()); + l2FloodDomainBuilder.setId(L2FD_ID); + if (external) { + l2FloodDomainBuilder.setId(L2_FD_ID_EXT); + } + l2FloodDomainBuilder.setParent(new L2BridgeDomainId(L2BD_ID)); + l2FloodDomainBuilder.addAugmentation(Segmentation.class, buildSegmentation().build()); l2FloodDomains.add(l2FloodDomainBuilder.build()); return l2FloodDomains; } - protected EndpointBuilder endpointBuilder(IpAddress ip, MacAddress mac, NodeConnectorId connector, - EndpointGroupId groupId, L2BridgeDomainId bridgeDomainId) { - EndpointBuilder endpointBuilder = new EndpointBuilder(); - - // Set tenant - endpointBuilder.setTenant(new TenantId(TENANT_ID)); - - // Set L3 address - if (ip != null) { - List l3Addresses = new ArrayList<>(); - L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); - l3AddressBuilder.setIpAddress(ip); - l3Addresses.add(l3AddressBuilder.build()); - endpointBuilder.setL3Address(l3Addresses); - } + protected List getL3AddressList(Ipv4Address l3IpAddress, L3ContextId l3ContextId) { + List l3Addresses = new ArrayList<>(); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(l3IpAddress)); + l3AddressBuilder.setL3Context(new L3ContextId(l3ContextId)); + l3Addresses.add(l3AddressBuilder.build()); + return l3Addresses; + } - // Set Mac address - endpointBuilder.setMacAddress(new MacAddress(mac)); - endpointBuilder.setL2Context(bridgeDomainId); - endpointBuilder.setEndpointGroup(groupId); + protected List getL3AddressList(Ipv6Address l3IpAddress) { + List l3Addresses = new ArrayList<>(); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(l3IpAddress)); + l3Addresses.add(l3AddressBuilder.build()); + return l3Addresses; + } - // Augment node connector + protected OfOverlayContextBuilder getOfOverlayContext(NodeConnectorId connector) { OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); - ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(connector)); - ofOverlayContextBuilder.setNodeId(nodeId); - endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + ofOverlayContextBuilder.setNodeConnectorId(connector); + ofOverlayContextBuilder.setNodeId(NODE_ID); + return ofOverlayContextBuilder; + } - // Set network containment - endpointBuilder.setNetworkContainment(new NetworkDomainId(DOMAIN_ID)); + protected EndpointBuilder buildEndpoint(Ipv4Address l3IpAddress, MacAddress mac, NodeConnectorId connector) { + EndpointBuilder endpointBuilder = new EndpointBuilder(); + endpointBuilder.setTenant(TENANT_ID); + endpointBuilder.setL3Address(getL3AddressList(l3IpAddress, L3C_ID)); + endpointBuilder.setMacAddress(new MacAddress(mac)); + endpointBuilder.setL2Context(new L2BridgeDomainId(L2BD_ID)); + endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0); + endpointBuilder.addAugmentation(OfOverlayContext.class, getOfOverlayContext(connector).build()); + endpointBuilder.setNetworkContainment(NET_DOMAIN_ID); + return endpointBuilder; + } + protected EndpointBuilder buildEndpoint(Ipv6Address l3IpAddress, MacAddress mac, NodeConnectorId connector) { + EndpointBuilder endpointBuilder = new EndpointBuilder(); + endpointBuilder.setTenant(TENANT_ID); + endpointBuilder.setL3Address(getL3AddressList(l3IpAddress)); + endpointBuilder.setMacAddress(new MacAddress(mac)); + endpointBuilder.setL2Context(new L2BridgeDomainId(L2BD_ID)); + endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0); + endpointBuilder.addAugmentation(OfOverlayContext.class, getOfOverlayContext(connector).build()); + endpointBuilder.setNetworkContainment(NET_DOMAIN_ID); return endpointBuilder; } - protected List endpointGroups() { + public List getEndpointGroups() { return ImmutableList.of( - new EndpointGroupBuilder().setId(eg) - .setNetworkDomain(sub) + new EndpointGroupBuilder().setId(ENDPOINT_GROUP_0) + .setNetworkDomain(SUBNET_0) .setConsumerNamedSelector(ImmutableList.of(new ConsumerNamedSelectorBuilder() - .setName(new SelectorName("cns1")).setContract(ImmutableList.of(cid)).build())) + .setName(new SelectorName("cns1")).setContract(ImmutableList.of(CONTRACT_ID)).build())) .build(), - new EndpointGroupBuilder().setId(eg2) - .setNetworkDomain(sub2) + new EndpointGroupBuilder().setId(ENDPOINT_GROUP_1) + .setNetworkDomain(SUBNET_1) .setProviderNamedSelector(ImmutableList.of(new ProviderNamedSelectorBuilder() - .setName(new SelectorName("pns1")).setContract(ImmutableList.of(cid)).build())) + .setName(new SelectorName("pns1")).setContract(ImmutableList.of(CONTRACT_ID)).build())) .build()); } - private SubjectFeatureInstances subjectFeatureInstances() { + protected SubjectFeatureInstances getSubjectFeatureInstances() { SubjectFeatureInstancesBuilder builder = new SubjectFeatureInstancesBuilder(); return builder.setClassifierInstance(ImmutableList.of(new ClassifierInstanceBuilder() .setName(new ClassifierName("tcp_dst_80")) .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) .setParameterValue(ImmutableList.of(new ParameterValueBuilder().setName(new ParameterName("destport")) - .setIntValue(80L) + .setIntValue(80L) // Endpoint + .build(), new ParameterValueBuilder().setName(new ParameterName("proto")) .setIntValue(6L) .build())) - .build(), new ClassifierInstanceBuilder().setName(new ClassifierName("tcp_src_80")) + .build(), new ClassifierInstanceBuilder().setName(new ClassifierName(TCP_SRC)) .setClassifierDefinitionId(Classifier.L4_CL.getId()) .setParameterValue(ImmutableList.of(new ParameterValueBuilder().setName(new ParameterName("sourceport")) .setIntValue(80L) @@ -268,41 +316,26 @@ public abstract class MapperUtilsTest { .build(); } - protected TenantBuilder baseTenantBuilder() { - TenantBuilder tenantBuilder = new TenantBuilder(); - tenantBuilder.setId(tid) - .setPolicy(new PolicyBuilder().setEndpointGroup(endpointGroups()) - .setSubjectFeatureInstances(subjectFeatureInstances()) - .build()) - .setForwardingContext(new ForwardingContextBuilder() - .setL3Context(ImmutableList.of(new L3ContextBuilder().setId(l3c).build())) - .setL2FloodDomain(l2FloodDomains()) - .setSubnet(subnet()) - .build()); - return tenantBuilder; - } - - protected List subnet() { + protected List getSubnetList() { return ImmutableList.of( - new SubnetBuilder().setId(sub2) - .setParent(fd) + new SubnetBuilder().setId(SUBNET_0) + .setParent(L2FD_ID) .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.1.0/24"))) .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.1.1"))) .build(), - new SubnetBuilder().setId(sub) - .setParent(fd) + new SubnetBuilder().setId(SUBNET_1) + .setParent(L2FD_ID) .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.0.0/24"))) .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.0.1"))) .build(), - new SubnetBuilder().setId(sub3) - .setParent(bd) + new SubnetBuilder().setId(SUBNET_2) + .setParent(L2BD_ID) .setIpPrefix(new IpPrefix(new Ipv4Prefix("10.0.2.0/24"))) .setVirtualRouterIp(new IpAddress(new Ipv4Address("10.0.2.1"))) .build(), - new SubnetBuilder() - .setId(ext_sub) + new SubnetBuilder().setId(SUBNET_EXT) + .setParent(L2_FD_ID_EXT) .setIpPrefix(new IpPrefix(new Ipv4Prefix("192.168.111.0/24"))) - .setParent(ext_fd) .build()); } } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlowsTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlowsTest.java new file mode 100644 index 000000000..78dba01b4 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperFlowsTest.java @@ -0,0 +1,1215 @@ +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.destination; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; +import org.opendaylight.groupbasedpolicy.dto.PolicyInfo; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.lang.reflect.Field; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.mockito.Mockito.*; +import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ OrdinalFactory.class }) +public class DestinationMapperFlowsTest extends MapperUtilsTest { + + private DestinationMapperFlows flows; + + @Before + public void init() throws Exception { + endpointManager = mock(EndpointManager.class); + policyManager = mock(PolicyManager.class); + policyInfo = mock(PolicyInfo.class); + ctx = mock(OfContext.class); + ofWriter = mock(OfWriter.class); + tableId = 3; + flows = new DestinationMapperFlows(new DestinationMapperUtils(ctx), NODE_ID, tableId); + resetPolicyOrdinalCounterValue(); + } + + @Test + public void testDropFlow_noEthertype() { + Flow testFlow = buildFlow(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build(); + + flows.dropFlow(100, null, ofWriter); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); + } + + @Test + public void testDropFlow_ipV4Ethertype() { + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4)); + Match match = matchBuilder.build(); + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + FlowUtils.dropInstructions()).build(); + + flows.dropFlow(100, FlowUtils.IPv4, ofWriter); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); + } + + @Test + public void testDropFlow_ipV6Ethertype() { + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6)); + Match match = matchBuilder.build(); + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + FlowUtils.dropInstructions()).build(); + + flows.dropFlow(100, FlowUtils.IPv6, ofWriter); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); + } + + @Test + public void testDropFlow_arpEthertype() { + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP)); + Match match = matchBuilder.build(); + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + FlowUtils.dropInstructions()).build(); + + flows.dropFlow(100, FlowUtils.ARP, ofWriter); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); + } + + @Test + public void createExternalL2Flow_exceptionCaught() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + Set externalConnectors = new HashSet<>(); + externalConnectors.add(new NodeConnectorId(CONNECTOR_0)); + externalConnectors.add(new NodeConnectorId(CONNECTOR_1)); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createExternalL2Flow(tableId, 100, endpointBuilder.build(), externalConnectors, ofWriter); + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createExternalL2Flow() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + Set externalConnectors = new HashSet<>(); + externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue())); + externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue())); + Endpoint endpoint = endpointBuilder.build(); + + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(ethernetMatch(null, endpoint.getMacAddress(), null)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) 0)); + Match match = matchBuilder.build(); + + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(tableId)) + .build(); + + ArrayList instructions = new ArrayList<>(); + instructions.add(applyActionsIns); + instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(instructions); + + FlowId flowId = FlowIdUtils.newFlowId(tableId, "externalL2", match); + Flow flow = buildFlow(flowId, tableId, 100, match, instructionsBuilder.build()).build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createExternalL2Flow(tableId, 100, endpointBuilder.build(), externalConnectors, ofWriter); + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createExternalL3RoutedFlow_nullIpAddress() { + EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + Endpoint gateway = gatewayBuilder.build(); + Endpoint endpoint = endpointBuilder.build(); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(null); + Set externalConnectors = new HashSet<>(); + externalConnectors.add(new NodeConnectorId(CONNECTOR_0)); + externalConnectors.add(new NodeConnectorId(CONNECTOR_1)); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors, + ofWriter); + + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createExternalL3RoutedFlow_exceptionCaught() { + EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + Endpoint gateway = gatewayBuilder.build(); + Endpoint endpoint = endpointBuilder.build(); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(new Ipv4Address(IPV4_0))); + Set externalConnectors = new HashSet<>(); + externalConnectors.add(new NodeConnectorId(CONNECTOR_0)); + externalConnectors.add(new NodeConnectorId(CONNECTOR_1)); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors, + ofWriter); + + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createExternalL3RoutedFlow_ipV4() { + EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + Endpoint gateway = gatewayBuilder.build(); + Endpoint endpoint = endpointBuilder.build(); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(new Ipv4Address(IPV4_0))); + Set externalConnectors = new HashSet<>(); + externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue())); + externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue())); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlSrcAction(new MacAddress(MAC_0))); + l3ApplyActions.add(setDlDstAction(new MacAddress(MAC_0))); + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + applyActions.addAll(l3ApplyActions); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, MAC_1, IPv4)) + .setLayer3Match(new Ipv4MatchBuilder() + .setIpv4Destination(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build()); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0)); + Match match = matchBuilder.build(); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(tableId)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(l3instructions); + + FlowId flowid = FlowIdUtils.newFlowId(tableId, "externalL3", match); + Flow flow = buildFlow(flowid, tableId, 90, match, instructionsBuilder.build()).build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors, + ofWriter); + + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createExternalL3RoutedFlow_ipV6() { + EndpointBuilder gatewayBuilder = buildEndpoint(IPV4_1, MAC_0, CONNECTOR_0); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_2, MAC_1, CONNECTOR_1); + Endpoint gateway = gatewayBuilder.build(); + Endpoint endpoint = endpointBuilder.build(); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(new Ipv6Address(IPV6_1))); + Set externalConnectors = new HashSet<>(); + externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue())); + externalConnectors.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue())); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlSrcAction(new MacAddress(MAC_0))); + l3ApplyActions.add(setDlDstAction(new MacAddress(MAC_0))); + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + applyActions.addAll(l3ApplyActions); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, MAC_1, IPv6)) + .setLayer3Match(new Ipv6MatchBuilder() + .setIpv6Destination(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128)).build()); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0)); + Match match = matchBuilder.build(); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(tableId)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(l3instructions); + + FlowId flowid = FlowIdUtils.newFlowId(tableId, "externalL3", match); + Flow flow = buildFlow(flowid, tableId, 90, match, instructionsBuilder.build()).build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createExternalL3RoutedFlow(tableId, 90, endpoint, gateway, l3AddressBuilder.build(), externalConnectors, + ofWriter); + + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createLocalL2Flow_exceptionCaught() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, CONNECTOR_0); + Endpoint endpoint = endpointBuilder.build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createLocalL2Flow(tableId, 80, endpoint, ofWriter); + + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createLocalL2Flow() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId); + Endpoint endpoint = endpointBuilder.build(); + + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(tableId)) + .build(); + + ArrayList instructions = new ArrayList<>(); + instructions.add(applyActionsIns); + instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(instructions); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, endpoint.getMacAddress(), + null)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) 0)); + Match match = matchBuilder.build(); + + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL2", match), tableId, 80, match, + instructionsBuilder.build()).build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createLocalL2Flow(tableId, 80, endpoint, ofWriter); + + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createLocalL3RoutedFlow_nullL3Context() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1)); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId); + endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + Endpoint endpoint = endpointBuilder.build(); + flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, null, null, ofWriter); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createLocalL3RoutedFlow_noMac() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1)); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId); + endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId()); + endpointBuilder.setMacAddress(null); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet localSubnet = localSubnetBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(SUBNET_0)); + Subnet destSubnet = destSubnetBuilder.build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + + flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, localSubnet, destSubnet, ofWriter); + verify(ctx, times(1)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createLocalL3RoutedFlow_sameSubnetIdAndExceptionCaught() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1)); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId); + endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId()); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet localSubnet = localSubnetBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + + flows.createLocalL3RoutedFlow(tableId, 80, endpoint, null, localSubnet, destSubnet, ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createLocalL3RoutedFlow_noIp() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1)); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId); + endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId()); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet localSubnet = localSubnetBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(CONTEXT_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(null); + L3Address l3Address = l3AddressBuilder.build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createLocalL3RoutedFlow_ipV4() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + MacAddress destMac = DestinationMapper.ROUTER_MAC; + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(connectorId)); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, connectorId); + endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId()); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet localSubnet = localSubnetBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(CONTEXT_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(new Ipv4Address(IPV4_0))); + L3Address l3Address = l3AddressBuilder.build(); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlDstAction((new MacAddress(MAC_1)))); + l3ApplyActions.add(decNwTtlAction()); + l3ApplyActions.add(setDlSrcAction(destMac)); + + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + applyActions.addAll(l3ApplyActions); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(tableId)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, new MacAddress(destMac), IPv4)) + .setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build()); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0)); + Match match = matchBuilder.build(); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(l3instructions); + + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL3", match), tableId, 80, match, + instructionsBuilder.build()).build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createLocalL3RoutedFlow_ipV6() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + MacAddress destMac = DestinationMapper.ROUTER_MAC; + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(connectorId); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1,MAC_1, connectorId); + endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId()); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet localSubnet = localSubnetBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(CONTEXT_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(new Ipv6Address(IPV6_1))); + L3Address l3Address = l3AddressBuilder.build(); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlDstAction((new MacAddress(MAC_1)))); + l3ApplyActions.add(decNwTtlAction()); + l3ApplyActions.add(setDlSrcAction(destMac)); + + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + applyActions.addAll(l3ApplyActions); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(tableId)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, new MacAddress(destMac), IPv6)) + .setLayer3Match(new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128)).build()); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0)); + Match match = matchBuilder.build(); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(l3instructions); + + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "localL3", match), tableId, 80, match, + instructionsBuilder.build()).build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createLocalL3RoutedFlow(tableId, 80, endpoint, l3Address, localSubnet, destSubnet, ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createRemoteL2Flow_exceptionCaught() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), null, null, new NodeConnectorId(CONNECTOR_1), + ofWriter); + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRemoteL2Flow_ipV4() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue()); + IpAddress ipAddress = new IpAddress(IPV4_0); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0); + EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_1, MAC_0, CONNECTOR_1); + + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadTunIPv4Action(ipAddress.getIpv4Address().getValue(), false)); + + int order = 0; + Instruction applyActionsIns = new InstructionBuilder().setOrder(order++) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(order) + .setInstruction(gotoTableIns(tableId)) + .build(); + + ArrayList instructions = new ArrayList<>(); + instructions.add(applyActionsIns); + instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(instructions); + + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(ethernetMatch(null, new MacAddress(MAC_0), null)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg4.class, (long) 0)); + Match match = matchBuilder.build(); + + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "remoteL2", match), tableId, 70, match, + instructionsBuilder.build()).build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), peerEndpointBuilder.build(), ipAddress, + connectorId, ofWriter); + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createRemoteL2Flow_ipV6() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_1); + IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1)); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0); + EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV6_2, MAC_0, CONNECTOR_0); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL2Flow(tableId, 70, endpointBuilder.build(), peerEndpointBuilder.build(), ipAddress, + connectorId, ofWriter); + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRemoteL3RoutedFlow_noL3Context() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0); + Endpoint endpoint = endpointBuilder.build(); + flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, null, null, null, null, ofWriter); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRemoteL3RoutedFlow_noMac() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0); + endpointBuilder.setMacAddress(null); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_1))); + Subnet localSubnet = localSubnetBuilder.build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, null, null, localSubnet, ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(2)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRemoteL3RoutedFlow_noIp() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_0); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_1))); + Subnet localSubnet = localSubnetBuilder.build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, null, null, localSubnet, ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRemoteL3RoutedFlow_incorrectPortId() { + IpAddress ipAddress = new IpAddress(new Ipv4Address(IPV4_0)); + NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_0); + EndpointBuilder endpointBuilder = buildEndpoint(IPV6_1,MAC_1,CONNECTOR_0); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(SUBNET_0)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_1))); + Subnet localSubnet = localSubnetBuilder.build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, null, destSubnet, ipAddress, connectorId, localSubnet, + ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRemoteL3RoutedFlow_ipV4() { + MacAddress routerMac = DestinationMapper.ROUTER_MAC; + IpAddress ipAddress = new IpAddress(new Ipv4Address(IPV4_1)); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(new Ipv4Address(IPV4_1))); + L3Address l3Address = l3AddressBuilder.build(); + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(SUBNET_0)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_1))); + Subnet localSubnet = localSubnetBuilder.build(); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlSrcAction(new MacAddress(routerMac))); + l3ApplyActions.add(setDlDstAction(new MacAddress(MAC_1))); + l3ApplyActions.add(decNwTtlAction()); + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadTunIPv4Action(IPV4_1.getValue(), false)); + applyActions.addAll(l3ApplyActions); + Instruction applyActionsIns = new InstructionBuilder().setOrder(0) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(1) + .setInstruction(gotoTableIns(tableId)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(l3instructions); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, new MacAddress(routerMac), IPv4)) + .setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_1.getValue() + IP_PREFIX_32)).build()); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0)); + Match match = matchBuilder.build(); + + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "remoteL3", match), tableId, 60, match, + instructionsBuilder.build()).build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, l3Address, destSubnet, ipAddress, connectorId, localSubnet, + ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(eq(NODE_ID), eq(tableId), eq(flow)); + } + + @Test + public void createRemoteL3RoutedFlow_ipV6() { + IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1)); + L3AddressBuilder l3AddressBuilder = new L3AddressBuilder(); + l3AddressBuilder.setIpAddress(new IpAddress(new Ipv4Address(IPV4_1))); + L3Address l3Address = l3AddressBuilder.build(); + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0); + Endpoint endpoint = endpointBuilder.build(); + + SubnetBuilder destSubnetBuilder = new SubnetBuilder(); + destSubnetBuilder.setId(new SubnetId(L3C_ID)); + Subnet destSubnet = destSubnetBuilder.build(); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(SUBNET_0)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_1))); + Subnet localSubnet = localSubnetBuilder.build(); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createRemoteL3RoutedFlow(tableId, 60, endpoint, l3Address, destSubnet, ipAddress, connectorId, localSubnet, + ofWriter); + verify(ctx, times(3)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRouterArpFlow_nullL3SubnetContext() throws Exception { + IndexedTenant tenant = getTestIndexedTenant(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId("otherSubnet")); + flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createRouterArpFlow_ipV4() throws Exception { + IndexedTenant tenant = getTestIndexedTenant(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(L3C_ID)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_0))); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP)) + .setLayer3Match(new ArpMatchBuilder().setArpOp(1) + .setArpTargetTransportAddress(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build()); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 1)); + Match match = matchBuilder.build(); + + List actions = new ArrayList<>(); + actions.add(nxMoveEthSrcToEthDstAction()); + actions.add(setDlSrcAction(new MacAddress(DestinationMapper.ROUTER_MAC))); + actions.add(nxLoadArpOpAction(BigInteger.valueOf(2L))); + actions.add(nxMoveArpShaToArpThaAction()); + actions.add(nxLoadArpShaAction(new BigInteger(1, bytesFromHexString(DestinationMapper.ROUTER_MAC.getValue())))); + actions.add(nxMoveArpSpaToArpTpaAction()); + actions.add(nxLoadArpSpaAction(IPV4_0.getValue())); + actions.add(outputAction(new NodeConnectorId(NODE_ID.getValue() + ":INPORT"))); + List instructions = new ArrayList<>(); + InstructionBuilder instructionBuilder = new InstructionBuilder(); + instructionBuilder.setInstruction(applyActionIns(actions.toArray(new Action[actions.size()]))).setOrder(0); + instructions.add(instructionBuilder.build()); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(instructions); + + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "routerarp", match), tableId, 50, match, + instructionsBuilder.build()).build(); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter); + + verify(ctx, times(1)).getEndpointManager(); + verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow)); + } + + @Test + public void createRouterArpFlow_ipV6() throws Exception { + IndexedTenant tenant = getTestIndexedTenant(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(L3C_ID)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv6Address(IPV6_1))); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + + flows.createRouterArpFlow(50, tenant, subnetBuilder.build(), ofWriter); + + verify(ctx, times(1)).getEndpointManager(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createBroadcastFlow() { + DestinationMapperUtils utils = new DestinationMapperUtils(ctx); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1); + endpointBuilder.setTenant(buildTenant().getId()); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpointBuilder.build()); + + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(1)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + + MatchBuilder matchBuilder = new MatchBuilder() + .setEthernetMatch(new EthernetMatchBuilder() + .setEthernetDestination(new EthernetDestinationBuilder().setAddress(new MacAddress(MAC_0)) + .setMask(new MacAddress(MAC_0)).build()) + .build()); + addNxRegMatch(matchBuilder, FlowUtils.RegMatch.of(NxmNxReg5.class, (long) ordinals.getFdId())); + Match match = matchBuilder.build(); + List actions = new ArrayList<>(); + actions.add(nxLoadTunIdAction(BigInteger.valueOf(ordinals.getFdId()), false)); + actions.add(groupAction((long) ordinals.getFdId())); + List instructions = new ArrayList<>(); + InstructionBuilder instructionBuilder = new InstructionBuilder(); + instructionBuilder.setInstruction(applyActionIns(actions.toArray(new Action[actions.size()]))).setOrder(0); + instructions.add(instructionBuilder.build()); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(instructions); + + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "broadcast", match), tableId, 40, match, + instructionsBuilder.build()).build(); + + flows.createBroadcastFlow(40, ordinals, new MacAddress(MAC_0), ofWriter); + + verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow)); + } + + @Test + public void createL3PrefixFlow_internalExceptionCaught() { + EndpointBuilder gatewayEp = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1)); + gatewayEp.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + + IndexedTenant tenant = getTestIndexedTenant(); + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_0))); + Subnet localSubnet = localSubnetBuilder.build(); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + + flows.createL3PrefixFlow(tableId, 30, gatewayEp.build(), null, tenant, localSubnet, null, ofWriter); + verify(ctx, times(1)).getEndpointManager(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createL3PrefixFlow_externalExceptionCaught() { + EndpointBuilder gatewayEpBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_1)); + gatewayEpBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + gatewayEpBuilder.setEndpointGroup(ENDPOINT_GROUP_0); + + TenantBuilder tenantBuilder = new TenantBuilder(getTestIndexedTenant().getTenant()); + List externalImplicitGroups = new ArrayList<>(); + ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder(); + externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0); + externalImplicitGroups.add(externalImplicitGroupBuilder.build()); + tenantBuilder.setPolicy(new PolicyBuilder().setExternalImplicitGroup(externalImplicitGroups).build()); + IndexedTenant tenant = new IndexedTenant(tenantBuilder.build()); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_0))); + Subnet localSubnet = localSubnetBuilder.build(); + + Set externalPorts = new HashSet<>(); + externalPorts.add(new NodeConnectorId(CONNECTOR_0)); + externalPorts.add(new NodeConnectorId(CONNECTOR_1)); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + + flows.createL3PrefixFlow(tableId, 30, gatewayEpBuilder.build(), null, tenant, localSubnet, externalPorts, + ofWriter); + verify(ctx, times(1)).getEndpointManager(); + verifyZeroInteractions(ofWriter); + } + + @Test + public void createL3PrefixFlow_internalIpV4() { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + EndpointBuilder gatewayEp = buildEndpoint(IPV4_0, MAC_0, connectorId); + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue())); + gatewayEp.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + + EndpointL3PrefixBuilder l3PrefixBuilder = new EndpointL3PrefixBuilder(); + l3PrefixBuilder.setIpPrefix(new IpPrefix(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32))); + EndpointL3Prefix l3Prefix = l3PrefixBuilder.build(); + + IndexedTenant tenant = getTestIndexedTenant(); + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_0))); + Subnet localSubnet = localSubnetBuilder.build(); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlDstAction(new MacAddress(MAC_0))); + l3ApplyActions.add(decNwTtlAction()); + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(1))); + applyActions.addAll(l3ApplyActions); + Instruction applyActionsIns = new InstructionBuilder().setOrder(0) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(1) + .setInstruction(gotoTableIns(tableId)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(l3instructions); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, + new MacAddress(DestinationMapper.ROUTER_MAC), IPv4)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0)); + Match match = matchBuilder.build(); + + Integer prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv4Prefix().getValue().split("/")[1]); + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "L3prefix", match), tableId, 30 + prefixLength, match, + instructionsBuilder.build()).build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createL3PrefixFlow(tableId, 30, gatewayEp.build(), l3Prefix, tenant, localSubnet, null, + ofWriter); + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(2)).getEndpointManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow)); + } + + @Test + public void createL3PrefixFlow_externalIpv6() throws Exception { + NodeConnectorId connectorId = new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue()); + EndpointBuilder gatewayEpBuilder = buildEndpoint(IPV6_1, MAC_0, connectorId); + + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(OPENFLOW + CONNECTOR_1)); + gatewayEpBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + gatewayEpBuilder.setEndpointGroup(ENDPOINT_GROUP_0); + + TenantBuilder tenantBuilder = new TenantBuilder(getTestIndexedTenant().getTenant()); + List externalImplicitGroups = new ArrayList<>(); + ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder(); + externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0); + externalImplicitGroups.add(externalImplicitGroupBuilder.build()); + tenantBuilder.setPolicy(new PolicyBuilder().setExternalImplicitGroup(externalImplicitGroups).build()); + IndexedTenant tenant = new IndexedTenant(tenantBuilder.build()); + + SubnetBuilder localSubnetBuilder = new SubnetBuilder(); + localSubnetBuilder.setId(new SubnetId(L3C_ID)); + localSubnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv6Address(IPV6_2))); + Subnet localSubnet = localSubnetBuilder.build(); + + Set externalPorts = new HashSet<>(); + externalPorts.add(new NodeConnectorId(OPENFLOW + CONNECTOR_0.getValue())); + externalPorts.add(new NodeConnectorId(OPENFLOW + CONNECTOR_1.getValue())); + + EndpointL3PrefixBuilder l3PrefixBuilder = new EndpointL3PrefixBuilder(); + l3PrefixBuilder.setIpPrefix(new IpPrefix(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128))); + EndpointL3Prefix l3Prefix = l3PrefixBuilder.build(); + + List l3ApplyActions = new ArrayList<>(); + l3ApplyActions.add(setDlDstAction(new MacAddress(MAC_0))); + l3ApplyActions.add(decNwTtlAction()); + List applyActions = new ArrayList<>(); + applyActions.add(nxLoadRegAction(NxmNxReg2.class, BigInteger.valueOf(1))); + applyActions.add(nxLoadRegAction(NxmNxReg3.class, BigInteger.valueOf(0))); + applyActions.add(nxLoadRegAction(NxmNxReg7.class, BigInteger.valueOf(0))); + applyActions.addAll(l3ApplyActions); + Instruction applyActionsIns = new InstructionBuilder().setOrder(0) + .setInstruction(applyActionIns(applyActions.toArray(new Action[applyActions.size()]))) + .build(); + Instruction gotoTable = new InstructionBuilder().setOrder(1) + .setInstruction(gotoTableIns(tableId)) + .build(); + ArrayList l3instructions = new ArrayList<>(); + l3instructions.add(applyActionsIns); + l3instructions.add(gotoTable); + InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); + instructionsBuilder.setInstruction(l3instructions); + + MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, + new MacAddress(DestinationMapper.ROUTER_MAC), IPv6)); + addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, (long) 0)); + Match match = matchBuilder.build(); + + Integer prefixLength = Integer.valueOf(l3Prefix.getIpPrefix().getIpv6Prefix().getValue().split("/")[1]); + Flow flow = buildFlow(FlowIdUtils.newFlowId(tableId, "L3prefix", match), tableId, 30 + prefixLength, match, + instructionsBuilder.build()).build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + flows.createL3PrefixFlow(tableId, 30, gatewayEpBuilder.build(), l3Prefix, tenant, localSubnet, externalPorts, + ofWriter); + + verify(ctx, times(4)).getTenant(any(TenantId.class)); + verify(ctx, times(3)).getEndpointManager(); + verify(ctx, times(2)).getCurrentPolicy(); + verify(ofWriter, times(1)).writeFlow(any(NodeId.class), anyShort(), eq(flow)); + } + + private void resetPolicyOrdinalCounterValue() throws Exception { + // TODO find better way, maybe fixed test method order? + Field field = OrdinalFactory.class.getDeclaredField("policyOrdinal"); + field.setAccessible(true); + field.set(null, new AtomicInteger(1)); + } +} \ No newline at end of file diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperTest.java new file mode 100644 index 000000000..40b3d0840 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperTest.java @@ -0,0 +1,433 @@ +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.destination; + + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; +import org.opendaylight.groupbasedpolicy.dto.EgKey; +import org.opendaylight.groupbasedpolicy.dto.EpKey; +import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; +import org.opendaylight.groupbasedpolicy.dto.PolicyInfo; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3GatewaysBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.PolicyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static junit.framework.TestCase.assertTrue; +import static org.mockito.Mockito.*; + +public class DestinationMapperTest extends MapperUtilsTest { + + private DestinationMapper destinationMapper; + + @Before + public void init() { + tableId = 3; + endpointManager = mock(EndpointManager.class); + policyManager = mock(PolicyManager.class); + switchManager = mock(SwitchManager.class); + policyInfo = mock(PolicyInfo.class); + ctx = mock(OfContext.class); + ofWriter = mock(OfWriter.class); + destinationMapper = new DestinationMapper(ctx, tableId); + } + + @Test + public void getTableId() { + assertTrue(destinationMapper.getTableId() == tableId); + } + + @Test + public void syncFlows() throws Exception { + DestinationMapperFlows flows = mock(DestinationMapperFlows.class); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getPolicyManager()).thenReturn(policyManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + destinationMapper.syncFlows(flows, endpointBuilder.build(), null, ofWriter); + + // Verify usage + verify(ctx, times(2)).getTenant(any(TenantId.class)); + verify(ctx, times(5)).getEndpointManager(); + verify(ctx, times(2)).getPolicyManager(); + verify(ctx, times(2)).getCurrentPolicy(); + + //Verify order + InOrder order = inOrder(flows); + order.verify(flows, times(1)).dropFlow(anyInt(), anyLong(), eq(ofWriter)); + order.verify(flows, times(1)).createBroadcastFlow(anyInt(), any(OrdinalFactory.EndpointFwdCtxOrdinals.class), + any(MacAddress.class), eq(ofWriter)); + } + + @Test + public void syncExternalEndpointFlows_L2Flow() { + DestinationMapperFlows flows = mock(DestinationMapperFlows.class); + // External ports + Set externalPorts = new HashSet<>(); + externalPorts.add(CONNECTOR_0); + externalPorts.add(CONNECTOR_1); + // Endpoint + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + // Peer endpoint + EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_2, MAC_0, CONNECTOR_0); + // External Implicit groups + List externalImplicitGroups = new ArrayList<>(); + ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder(); + externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0); + externalImplicitGroups.add(externalImplicitGroupBuilder.build()); + TenantBuilder peerTenantBuilder = buildTenant(); + peerTenantBuilder.setPolicy(new PolicyBuilder() + .setEndpointGroup(getEndpointGroups()) + .setSubjectFeatureInstances(getSubjectFeatureInstances()) + .setExternalImplicitGroup(externalImplicitGroups) + .build()); + Endpoint peerEndpoint = peerEndpointBuilder.build(); + Collection peerEndpoints = new ArrayList<>(); + peerEndpoints.add(peerEndpoint); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(peerTenantBuilder.build())); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getPolicyManager()).thenReturn(policyManager); + when(ctx.getSwitchManager()).thenReturn(switchManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + when(endpointManager.getEndpointsForGroup(any(EgKey.class))).thenReturn(peerEndpoints); + when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(peerEndpoints); + when(switchManager.getExternalPorts(any(NodeId.class))).thenReturn(externalPorts); + + destinationMapper.syncEndpointFlows(flows, NODE_ID, endpointBuilder.build(), ofWriter); + + // Verify usage + verify(ctx, times(11)).getTenant(any(TenantId.class)); + verify(ctx, times(6)).getEndpointManager(); + verify(ctx, times(1)).getPolicyManager(); + verify(ctx, times(4)).getCurrentPolicy(); + verify(flows, times(1)).createExternalL2Flow(anyShort(), anyInt(), any(Endpoint.class), + anySetOf(NodeConnectorId.class), eq(ofWriter)); + } + + @Test + public void syncExternalEndpointFlows_L3Flow() { + DestinationMapperFlows flows = mock(DestinationMapperFlows.class); + // L3 Endpoint prefix + Collection endpointL3PrefixCollection = new HashSet<>(); + List endpointL3GatewaysList = new ArrayList<>(); + EndpointL3PrefixBuilder endpointL3PrefixBuilder = new EndpointL3PrefixBuilder(); + EndpointL3GatewaysBuilder endpointL3GatewaysBuilder = new EndpointL3GatewaysBuilder(); + endpointL3GatewaysList.add(endpointL3GatewaysBuilder.build()); + endpointL3PrefixBuilder.setEndpointL3Gateways(endpointL3GatewaysList); + endpointL3PrefixCollection.add(endpointL3PrefixBuilder.build()); + // External ports + Set externalPorts = new HashSet<>(); + externalPorts.add(new NodeConnectorId(CONNECTOR_0)); + externalPorts.add(new NodeConnectorId(CONNECTOR_1)); + // Endpoint + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + endpointBuilder.setL3Address(getL3AddressList(IPV4_1, L3C_ID)); + endpointBuilder.setNetworkContainment(new NetworkDomainId(SUBNET_0)); + Endpoint endpoint = endpointBuilder.build(); + // Peer + EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_2, MAC_0, CONNECTOR_0); + peerEndpointBuilder.setNetworkContainment(new NetworkDomainId(SUBNET_0)); + // External implicit groups + List subnets = new ArrayList<>(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_0)); + subnetBuilder.setParent(new ContextId(L3C_ID)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_2))); + subnets.add(subnetBuilder.build()); + List l3Contexts = new ArrayList<>(); + L3ContextBuilder l3ContextBuilder = new L3ContextBuilder(); + l3ContextBuilder.setId(L3C_ID); + l3Contexts.add(l3ContextBuilder.build()); + List externalImplicitGroups = new ArrayList<>(); + ExternalImplicitGroupBuilder externalImplicitGroupBuilder = new ExternalImplicitGroupBuilder(); + externalImplicitGroupBuilder.setId(ENDPOINT_GROUP_0); + externalImplicitGroups.add(externalImplicitGroupBuilder.build()); + ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder(); + forwardingContextBuilder.setSubnet(subnets); + forwardingContextBuilder.setL3Context(l3Contexts); + TenantBuilder peerTenantBuilder = buildTenant(); + peerTenantBuilder.setForwardingContext(forwardingContextBuilder.build()); + peerTenantBuilder.setPolicy(new PolicyBuilder() + .setSubjectFeatureInstances(getSubjectFeatureInstances()) + .setEndpointGroup(getEndpointGroups()) + .setExternalImplicitGroup(externalImplicitGroups) + .build()); + Tenant peerTenant = peerTenantBuilder.build(); + peerEndpointBuilder.setNetworkContainment(new NetworkDomainId(SUBNET_1)); + Endpoint peerEndpoint = peerEndpointBuilder.build(); + Collection peerEndpoints = new ArrayList<>(); + peerEndpoints.add(peerEndpoint); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(peerTenant)); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getPolicyManager()).thenReturn(policyManager); + when(ctx.getSwitchManager()).thenReturn(switchManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + when(endpointManager.getEndpointsForGroup(any(EgKey.class))).thenReturn(peerEndpoints); + when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(peerEndpoints); + when(endpointManager.getEndpointsL3PrefixForTenant(any(TenantId.class))).thenReturn(endpointL3PrefixCollection); + when(endpointManager.getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), any(TenantId.class))) + .thenReturn(buildL3Endpoint(IPV4_1, IPV4_2, MAC_0, L2BD_ID.getValue()).build()); + when(endpointManager.getEndpoint(any(EpKey.class))).thenReturn(endpoint); + when(switchManager.getExternalPorts(any(NodeId.class))).thenReturn(externalPorts); + + destinationMapper.syncEndpointFlows(flows, NODE_ID, endpoint, ofWriter); + + // Verify usage + verify(ctx, times(13)).getTenant(any(TenantId.class)); + verify(ctx, times(9)).getEndpointManager(); + verify(ctx, times(1)).getPolicyManager(); + verify(ctx, times(4)).getCurrentPolicy(); + verify(flows, times(1)).createExternalL3RoutedFlow(anyShort(), anyInt(), any(Endpoint.class), any(Endpoint.class), + any(L3Address.class), anySetOf(NodeConnectorId.class), eq(ofWriter)); + } + + @Test + public void syncLocalEndpointFlows() { + DestinationMapperFlows flows = mock(DestinationMapperFlows.class); + // Endpoint + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + endpointBuilder.setNetworkContainment(SUBNET_0); + // Peer + EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_2, MAC_0, CONNECTOR_0); + // Subnets, l3Context and forwarding context + List subnets = new ArrayList<>(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_0)); + subnetBuilder.setParent(new ContextId(L3C_ID)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_2))); + subnets.add(subnetBuilder.build()); + List l3Contexts = new ArrayList<>(); + L3ContextBuilder l3ContextBuilder = new L3ContextBuilder(); + l3ContextBuilder.setId(L3C_ID); + l3Contexts.add(l3ContextBuilder.build()); + ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder(); + forwardingContextBuilder.setSubnet(subnets); + forwardingContextBuilder.setL3Context(l3Contexts); + TenantBuilder peerTenantBuilder = new TenantBuilder(getTestIndexedTenant().getTenant()); + peerTenantBuilder.setForwardingContext(forwardingContextBuilder.build()); + Tenant peerTenant = peerTenantBuilder.build(); + peerEndpointBuilder.setNetworkContainment(new NetworkDomainId(SUBNET_0)); + Endpoint peerEndpoint = peerEndpointBuilder.build(); + Collection peerEndpoints = new ArrayList<>(); + peerEndpoints.add(peerEndpoint); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(peerTenant)); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getPolicyManager()).thenReturn(policyManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + when(endpointManager.getEndpointsForGroup(any(EgKey.class))).thenReturn(peerEndpoints); + when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(peerEndpoints); + + destinationMapper.syncFlows(flows, endpointBuilder.build(), NODE_ID, ofWriter); + + // Verify usage + verify(ctx, times(18)).getTenant(any(TenantId.class)); + verify(ctx, times(9)).getEndpointManager(); + verify(ctx, times(2)).getPolicyManager(); + verify(ctx, times(4)).getCurrentPolicy(); + + // Verify order + InOrder order = inOrder(flows); + order.verify(flows, times(1)).createLocalL2Flow(anyShort(), anyInt(), any(Endpoint.class), eq(ofWriter)); + order.verify(flows, times(1)).createLocalL3RoutedFlow(anyShort(), anyInt(), any(Endpoint.class), + any(L3Address.class), any(Subnet.class), any(Subnet.class), eq(ofWriter)); + } + + @Test + public void syncRemoteEndpointFlows() { + DestinationMapperFlows flows = mock(DestinationMapperFlows.class); + // Endpoint + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + // Peer + EndpointBuilder peerEndpointBuilder = buildEndpoint(IPV4_2, MAC_0, CONNECTOR_0); + // Subnets, l3Context and forwarding context + List subnets = new ArrayList<>(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_0)); + subnetBuilder.setParent(new ContextId(L3C_ID)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_2))); + subnets.add(subnetBuilder.build()); + List l3Contexts = new ArrayList<>(); + L3ContextBuilder l3ContextBuilder = new L3ContextBuilder(); + l3ContextBuilder.setId(L3C_ID); + l3Contexts.add(l3ContextBuilder.build()); + ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder(); + forwardingContextBuilder.setSubnet(subnets); + forwardingContextBuilder.setL3Context(l3Contexts); + TenantBuilder peerTenantBuilder = buildTenant(); + peerTenantBuilder.setForwardingContext(forwardingContextBuilder.build()); + Tenant peerTenant = peerTenantBuilder.build(); + // Augmentation + OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder(); + ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(CONNECTOR_0)); + ofOverlayContextBuilder.setNodeId(new NodeId("remoteNodeID")); + peerEndpointBuilder.setNetworkContainment(new NetworkDomainId(SUBNET_0)); + peerEndpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build()); + Endpoint peerEndpoint = peerEndpointBuilder.build(); + Collection peerEndpoints = new ArrayList<>(); + peerEndpoints.add(peerEndpoint); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(peerTenant)); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getPolicyManager()).thenReturn(policyManager); + when(ctx.getSwitchManager()).thenReturn(switchManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + when(endpointManager.getEndpointsForGroup(any(EgKey.class))).thenReturn(peerEndpoints); + when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(peerEndpoints); + when(switchManager.getTunnelIP(any(NodeId.class), eq(TunnelTypeVxlan.class))) + .thenReturn(new IpAddress(new Ipv4Address(IPV4_2))); + when(switchManager.getTunnelPort(any(NodeId.class), eq(TunnelTypeVxlan.class))) + .thenReturn(new NodeConnectorId(CONNECTOR_2)); + + destinationMapper.syncEndpointFlows(flows, NODE_ID, endpointBuilder.build(), ofWriter); + + // Verify usage + verify(ctx, times(13)).getTenant(any(TenantId.class)); + verify(ctx, times(5)).getEndpointManager(); + verify(ctx, times(1)).getPolicyManager(); + verify(ctx, times(3)).getCurrentPolicy(); + + // Verify order + InOrder order = inOrder(flows); + order.verify(flows, times(1)).createRemoteL2Flow(anyShort(), anyInt(), any(Endpoint.class), any(Endpoint.class), + any(IpAddress.class), any(NodeConnectorId.class), eq(ofWriter)); + order.verify(flows, times(1)).createRemoteL3RoutedFlow(anyShort(), anyInt(), any(Endpoint.class), + any(L3Address.class), any(Subnet.class), any(IpAddress.class), any(NodeConnectorId.class), + any(Subnet.class), eq(ofWriter)); + } + + @Test + public void syncArpFlow() throws Exception { + DestinationMapperFlows flows = mock(DestinationMapperFlows.class); + // Subnets, l3Context and forwarding context + List l3Contexts = new ArrayList<>(); + L3ContextBuilder l3ContextBuilder = new L3ContextBuilder(); + l3ContextBuilder.setId(L3C_ID); + l3Contexts.add(l3ContextBuilder.build()); + HashSet subnets = new HashSet<>(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_0)); + subnetBuilder.setParent(new ContextId(L3C_ID)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_2))); + subnets.add(subnetBuilder.build()); + ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder(); + forwardingContextBuilder.setSubnet(new ArrayList<>(subnets)); + forwardingContextBuilder.setL3Context(l3Contexts); + TenantBuilder tenantBuilder = buildTenant(); + tenantBuilder.setForwardingContext(forwardingContextBuilder.build()); + Tenant tenant = tenantBuilder.build(); + destinationMapper.subnetsByTenant.put(tenant.getId(), subnets); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(tenant)); + + destinationMapper.syncArpFlow(flows, tenant.getId(), ofWriter); + + verify(ctx, times(1)).getTenant(any(TenantId.class)); + verify(flows, times(1)).createRouterArpFlow(anyInt(), any(IndexedTenant.class), any(Subnet.class), eq(ofWriter)); + } + + @Test + public void syncL3PrefixFlow() { + DestinationMapperFlows flows = mock(DestinationMapperFlows.class); + // Subnets, l3Context and forwarding context + List l3Contexts = new ArrayList<>(); + L3ContextBuilder l3ContextBuilder = new L3ContextBuilder(); + l3ContextBuilder.setId(L3C_ID); + l3Contexts.add(l3ContextBuilder.build()); + HashSet subnets = new HashSet<>(); + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_0)); + subnetBuilder.setParent(new ContextId(L3C_ID)); + subnetBuilder.setVirtualRouterIp(new IpAddress(IPV4_2)); + subnets.add(subnetBuilder.build()); + ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder(); + forwardingContextBuilder.setL3Context(l3Contexts); + forwardingContextBuilder.setSubnet(new ArrayList<>(subnets)); + TenantBuilder tenantBuilder = buildTenant(); + tenantBuilder.setForwardingContext(forwardingContextBuilder.build()); + Tenant tenant = tenantBuilder.build(); + Collection endpoints = new ArrayList<>(); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1); + endpointBuilder.setNetworkContainment(new NetworkDomainId(SUBNET_0)); + Endpoint endpoint = endpointBuilder.build(); + endpoints.add(endpoint); + + ArrayList l3Prefixes = new ArrayList<>(); + EndpointL3PrefixBuilder prefixBuilder = new EndpointL3PrefixBuilder(); + List endpointL3GatewaysList = new ArrayList<>(); + EndpointL3GatewaysBuilder endpointL3GatewaysBuilder = new EndpointL3GatewaysBuilder(); + endpointL3GatewaysBuilder.setIpAddress(new IpAddress(new Ipv4Address(IPV4_1))); + endpointL3GatewaysBuilder.setL3Context(L3C_ID); + endpointL3GatewaysList.add(endpointL3GatewaysBuilder.build()); + prefixBuilder.setEndpointL3Gateways(endpointL3GatewaysList); + l3Prefixes.add(prefixBuilder.build()); + + EndpointL3 endpointL3 = buildL3Endpoint(IPV4_0, IPV4_2, MAC_2, L2).build(); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(tenant)); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getSwitchManager()).thenReturn(switchManager); + when(ctx.getPolicyManager()).thenReturn(policyManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(endpoints); + when(endpointManager.getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), any(TenantId.class))) + .thenReturn(endpointL3); + when(endpointManager.getL2EndpointFromL3(any(EndpointL3.class))).thenReturn(endpoint); + + destinationMapper.syncL3PrefixFlow(flows, l3Prefixes, null, NODE_ID, ofWriter); + + verify(ctx, times(5)).getTenant(any(TenantId.class)); + verify(ctx, times(4)).getEndpointManager(); + verify(ctx, times(1)).getSwitchManager(); + verify(ctx, times(1)).getPolicyManager(); + verify(ctx, times(1)).getCurrentPolicy(); + verify(flows, times(1)).createL3PrefixFlow(anyShort(), anyInt(), any(Endpoint.class), any(EndpointL3Prefix.class), + any(IndexedTenant.class), any(Subnet.class), anySetOf(NodeConnectorId.class), eq(ofWriter)); + } + +} \ No newline at end of file diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtilsTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtilsTest.java new file mode 100644 index 000000000..1702c9ff6 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/destination/DestinationMapperUtilsTest.java @@ -0,0 +1,330 @@ +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.destination; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.groupbasedpolicy.dto.EpKey; +import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; +import org.opendaylight.groupbasedpolicy.dto.PolicyInfo; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2ContextId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3GatewaysBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.TestCase.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; + +public class DestinationMapperUtilsTest extends MapperUtilsTest { + + private DestinationMapperUtils utils; + + @Before + public void init() { + endpointManager = mock(EndpointManager.class); + policyInfo = mock(PolicyInfo.class); + ctx = mock(OfContext.class); + utils = new DestinationMapperUtils(ctx); + } + + @Test + public void getSubnets() { + EndpointBuilder endpointBuilder = new EndpointBuilder(); + HashSet emptyArray = utils.getSubnets(endpointBuilder.build().getTenant()); + assertTrue(emptyArray.equals(Collections.emptySet())); + + List subnets = getSubnetList(); + Tenant tenant = buildTenant().build(); + endpointBuilder.setTenant(tenant.getId()); + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(tenant)); + + HashSet result = utils.getSubnets(endpointBuilder.build().getTenant()); + List resultAsList = new ArrayList<>(result); + assertTrue(subnets.containsAll(resultAsList)); + } + + @Test + public void getL3ContextForSubnet_nullTenant() { + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_2)); + L3Context l3Context = utils.getL3ContextForSubnet(null, subnetBuilder.build()); + assertNull(l3Context); + } + + @Test + public void getL3ContextForSubnet_nullResult() { + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId("otherSubnet")); + L3Context l3Context = utils.getL3ContextForSubnet(getTestIndexedTenant(), subnetBuilder.build()); + assertNull(l3Context); + } + + @Test + public void getL3ContextForSubnet_l3Context() { + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(L3C_ID)); + + // expected result + L3ContextBuilder expectedL3Context = new L3ContextBuilder(); + expectedL3Context.setId(new L3ContextId(L3C_ID)); + + L3Context l3Context = utils.getL3ContextForSubnet(getTestIndexedTenant(), subnetBuilder.build()); + assertEquals(l3Context, expectedL3Context.build()); + } + + @Test + public void getEpNetworkContainment_getNull() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1); + endpointBuilder.setNetworkContainment(null); + + NetworkDomainId result = utils.getEPNetworkContainment(endpointBuilder.build(), null); + assertNull(result); + } + + @Test + public void getEpNetworkContainment_getDomainIdFromEpg() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1); + endpointBuilder.setNetworkContainment(null); + EndpointGroupBuilder endpointGroupBuilder = new EndpointGroupBuilder(); + endpointGroupBuilder.setId(ENDPOINT_GROUP_0); + endpointGroupBuilder.setNetworkDomain(new NetworkDomainId(NET_DOMAIN_ID)); + endpointBuilder.setEndpointGroup(endpointGroupBuilder.build().getId()); + + NetworkDomainId result = utils.getEPNetworkContainment(endpointBuilder.build(), getTestIndexedTenant()); + assertEquals(result, new SubnetId(SUBNET_0)); + } + + @Test + public void getEpNetworkContainment_getDomainIdFromEndpoint() { + String domainId = "domainId"; + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1); + endpointBuilder.setNetworkContainment(new NetworkDomainId(domainId)); + + NetworkDomainId result = utils.getEPNetworkContainment(endpointBuilder.build(), getTestIndexedTenant()); + assertEquals(result, new NetworkDomainId(domainId)); + } + + @Test + public void getLocalSubnets() { + Collection endpoints = new ArrayList<>(); + EndpointBuilder epWithoutSubnet = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1); + epWithoutSubnet.setTenant(null); + EndpointBuilder epWithSubnet = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_1); + TenantBuilder tenantBuilder = new TenantBuilder(buildTenant().build()); + Tenant tenant = tenantBuilder.build(); + epWithSubnet.setTenant(tenant.getId()); + epWithSubnet.setNetworkContainment(new NetworkDomainId(SUBNET_0)); + epWithSubnet.setTenant(tenant.getId()); + epWithSubnet.setNetworkContainment(new NetworkDomainId(SUBNET_1)); + endpoints.add(epWithoutSubnet.build()); + endpoints.add(epWithSubnet.build()); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getTenant(null)).thenReturn(null); + when(ctx.getTenant(tenant.getId())).thenReturn(new IndexedTenant(tenant)); + when(endpointManager.getEndpointsForNode(NODE_ID)).thenReturn(endpoints); + + List subnets = utils.getLocalSubnets(NODE_ID); + verify(endpointManager, times(1)).getEndpointsForNode(any(NodeId.class)); + assertTrue(subnets.size() == 1); + } + + @Test + public void getL2EpOfSubnetGateway_nullCase() { + Endpoint result = utils.getL2EpOfSubnetGateway(buildTenant().getId(), null); + assertNull(result); + } + + @Test + public void getL2EpOfSubnetGateway_nullL3Prefix() { + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_0)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_0))); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(endpointManager.getEndpointsL3PrefixForTenant(buildTenant().getId())).thenReturn(null); + + Endpoint result = utils.getL2EpOfSubnetGateway(buildTenant().getId(), subnetBuilder.build()); + assertNull(result); + } + + @Test + public void getL2EpOfSubnetGateway_emptyL3Prefix() { + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_2)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_0))); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(endpointManager.getEndpointsL3PrefixForTenant(buildTenant().getId())) + .thenReturn(new ArrayList()); + + Endpoint result = utils.getL2EpOfSubnetGateway(buildTenant().getId(), subnetBuilder.build()); + assertNull(result); + } + + @Test + public void getL2EpOfSubnetGateway() { + SubnetBuilder subnetBuilder = new SubnetBuilder(); + subnetBuilder.setId(new SubnetId(SUBNET_1)); + subnetBuilder.setVirtualRouterIp(new IpAddress(new Ipv4Address(IPV4_0))); + + // L3 Prefix + Collection l3PrefixCollection = new ArrayList<>(); + EndpointL3PrefixBuilder endpointL3PrefixBuilder = new EndpointL3PrefixBuilder(); + List endpointL3GatewaysList = new ArrayList<>(); + EndpointL3GatewaysBuilder endpointL3GatewaysBuilder = new EndpointL3GatewaysBuilder(); + endpointL3GatewaysList.add(endpointL3GatewaysBuilder.build()); + endpointL3PrefixBuilder.setEndpointL3Gateways(endpointL3GatewaysList); + endpointL3GatewaysBuilder.setL3Context(new L3ContextBuilder().setId(new L3ContextId("l3cId")).build().getId()); + l3PrefixCollection.add(endpointL3PrefixBuilder.build()); + + // L3 Endpoint + EndpointL3Builder endpointL3Builder = new EndpointL3Builder(); + endpointL3Builder.setL2Context(new L2BridgeDomainBuilder().setId(new L2BridgeDomainId("bdId")).build().getId()); + endpointL3Builder.setMacAddress(new MacAddress(MAC_0)); + + // Endpoint + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(endpointManager.getEndpointsL3PrefixForTenant(buildTenant().getId())).thenReturn(l3PrefixCollection); + when(endpointManager.getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), + any(TenantId.class))).thenReturn(endpointL3Builder.build()); + when(endpointManager.getEndpoint(any(EpKey.class))).thenReturn(endpointBuilder.build()); + + Endpoint result = utils.getL2EpOfSubnetGateway(buildTenant().getId(), subnetBuilder.build()); + verify(endpointManager, times(1)).getEndpointsL3PrefixForTenant(any(TenantId.class)); + verify(endpointManager, times(1)).getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), + Mockito.any(TenantId.class)); + verify(endpointManager, times(1)).getEndpoint(any(EpKey.class)); + assertNotNull(result); + } + + @Test + public void routerPortMac_noL3ContextId() { + L3ContextBuilder contextBuilder = new L3ContextBuilder(); + MacAddress result = utils.routerPortMac(contextBuilder.build(), new IpAddress(new Ipv4Address(IPV4_0)), + buildTenant().getId()); + assertEquals(result, DestinationMapper.ROUTER_MAC); + } + + @Test + public void routerPortMac_nullEp() { + L3ContextBuilder contextBuilder = new L3ContextBuilder(); + contextBuilder.setId(new L3ContextId("l3id")); + L3Context context = contextBuilder.build(); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(endpointManager.getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), any(TenantId.class))) + .thenReturn(null); + + MacAddress result = utils.routerPortMac(context, new IpAddress(new Ipv4Address(IPV4_0)), + buildTenant().getId()); + + verify(endpointManager, times(1)).getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), + any(TenantId.class)); + assertEquals(result, DestinationMapper.ROUTER_MAC); + } + + @Test + public void routerPortMac() { + L3ContextBuilder contextBuilder = new L3ContextBuilder(); + contextBuilder.setId(new L3ContextId("l3id")); + L3Context context = contextBuilder.build(); + EndpointL3Builder endpointL3Builder = buildL3Endpoint(IPV4_0, IPV4_1, MAC_0, L2); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(endpointManager.getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), any(TenantId.class))) + .thenReturn(endpointL3Builder.build()); + + MacAddress result = utils.routerPortMac(context, new IpAddress(new Ipv4Address(IPV4_0)), + buildTenant().getId()); + + verify(endpointManager, times(1)).getL3Endpoint(any(L3ContextId.class), any(IpAddress.class), + any(TenantId.class)); + assertEquals(result, new MacAddress(MAC_0)); + } + + @Test + public void getAllEndpointGroups() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0); + List endpointGroups = new ArrayList<>(); + EndpointGroupBuilder endpointGroupBuilder = new EndpointGroupBuilder(); + endpointGroupBuilder.setId(ENDPOINT_GROUP_1); + endpointGroups.add(endpointGroupBuilder.build().getId()); + endpointBuilder.setEndpointGroups(endpointGroups); + + Set result = utils.getAllEndpointGroups(endpointBuilder.build()); + assertTrue(result.size() == 2); + } + + @Test + public void getEndpointOrdinals_exceptionCaught() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpointBuilder.build()); + assertNull(ordinals); + } + + @Test + public void getEndpointOrdinals() { + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0); + + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + + OrdinalFactory.EndpointFwdCtxOrdinals ordinals = utils.getEndpointOrdinals(endpointBuilder.build()); + assertEquals(ordinals.getEp().toString(), new EpKey(new L2ContextId(L2BD_ID), new MacAddress(MAC_0)).toString()); + assertEquals(ordinals.getNetworkContainment(), NET_DOMAIN_ID); + } + + @Test + public void getIndexedTenant() { + TenantBuilder tenantBuilder = buildTenant(); + tenantBuilder.setId(TENANT_ID); + when(ctx.getTenant(TENANT_ID)).thenReturn(new IndexedTenant(tenantBuilder.build())); + IndexedTenant result = utils.getIndexedTenant(TENANT_ID); + assertTrue(result.getTenant().getId().equals(TENANT_ID)); + } +} \ No newline at end of file diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlowsTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlowsTest.java index c1d627a27..7e4cc096b 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlowsTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlowsTest.java @@ -19,7 +19,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.M import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; @@ -31,10 +32,7 @@ import static org.mockito.Mockito.*; public class EgressNatMapperFlowsTest extends MapperUtilsTest { - private static final String DROP = "drop"; - private static final String DROP_ALL = "dropAll"; private static final String EGRESS_NAT = "EgressNat|"; - private final NodeId nodeId = new NodeId(NODE_ID); private EgressNatMapperFlows flows; private short tableId; @@ -42,16 +40,16 @@ public class EgressNatMapperFlowsTest extends MapperUtilsTest { public void init() { tableId = 5; ofWriter = mock(OfWriter.class); - flows = new EgressNatMapperFlows(nodeId, tableId); + flows = new EgressNatMapperFlows(NODE_ID, tableId); } @Test public void testDropFlow_noEthertype() { - Flow testFlow = flowBuilder(new FlowId(DROP_ALL), tableId, 100, null, + Flow testFlow = buildFlow(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, null, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -59,11 +57,11 @@ public class EgressNatMapperFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.IPv4, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -71,11 +69,11 @@ public class EgressNatMapperFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.IPv6, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -83,32 +81,34 @@ public class EgressNatMapperFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.ARP, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testNatFlows_noAugmentation() { - EndpointL3 endpointL3 = endpointL3Builder(null, IPV4_1, MAC_0, L2, false).build(); - flows.natFlows((short) 6, endpointL3, 100, ofWriter); + EndpointL3Builder endpointL3Builder = buildL3Endpoint(IPV4_1, IPV4_0, MAC_0, L2); + endpointL3Builder.addAugmentation(NatAddress.class, null); + flows.natFlows((short) 6, endpointL3Builder.build(), 100, ofWriter); verifyZeroInteractions(ofWriter); } @Test public void testNatFlows_ipv4() { - EndpointL3 endpointL3 = endpointL3Builder(IPV4_1, IPV4_2, MAC_0, L2, false).build(); + EndpointL3 endpointL3 = buildL3Endpoint(IPV4_0, IPV4_1, MAC_0, L2).build(); MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4)) - .setLayer3Match(new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(IPV4_2 + IP_PREFIX_32)).build()); + .setLayer3Match(new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(IPV4_1.getValue() + IP_PREFIX_32)) + .build()); FlowUtils.addNxRegMatch(matchBuilder, FlowUtils.RegMatch.of(NxmNxReg6.class, (long) 0)); Match match = matchBuilder.build(); InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); InstructionBuilder apply = new InstructionBuilder(); - apply.setOrder(0).setInstruction(FlowUtils.applyActionIns(FlowUtils.setIpv4SrcAction(new Ipv4Address(IPV4_1)))); + apply.setOrder(0).setInstruction(FlowUtils.applyActionIns(FlowUtils.setIpv4SrcAction(new Ipv4Address(IPV4_0)))); InstructionBuilder goTo = new InstructionBuilder(); goTo.setOrder(1).setInstruction(FlowUtils.gotoTableIns((short) 6)); List instructions = new ArrayList<>(); @@ -116,19 +116,20 @@ public class EgressNatMapperFlowsTest extends MapperUtilsTest { instructions.add(goTo.build()); instructionsBuilder.setInstruction(instructions); - Flow testFlow = flowBuilder(new FlowId(EGRESS_NAT + new IpAddress(new Ipv4Address(IPV4_2)) + "|" + - new IpAddress(new Ipv4Address(IPV4_1))), tableId, 90, match, instructionsBuilder.build()).build(); + Flow testFlow = buildFlow(new FlowId(EGRESS_NAT + new IpAddress(new Ipv4Address(IPV4_1)) + "|" + + new IpAddress(new Ipv4Address(IPV4_0))), tableId, 90, match, instructionsBuilder.build()).build(); flows.natFlows((short) 6, endpointL3, 90, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testNatFlows_ipv6() { - EndpointL3 endpointL3 = endpointL3Builder(IPV6_1, IPV6_2, MAC_0, L2, true).build(); + EndpointL3 endpointL3 = buildL3Endpoint(IPV6_1, IPV6_2, MAC_0, L2).build(); MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6)) - .setLayer3Match(new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(IPV6_2 + IP_PREFIX_128)).build()); + .setLayer3Match(new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(IPV6_2.getValue() + + IP_PREFIX_128)).build()); FlowUtils.addNxRegMatch(matchBuilder, FlowUtils.RegMatch.of(NxmNxReg6.class, (long) 0)); Match match = matchBuilder.build(); @@ -142,11 +143,11 @@ public class EgressNatMapperFlowsTest extends MapperUtilsTest { instructions.add(goTo.build()); instructionsBuilder.setInstruction(instructions); - Flow testFlow = flowBuilder(new FlowId(EGRESS_NAT + new IpAddress(new Ipv6Address(IPV6_2)) + "|" + + Flow testFlow = buildFlow(new FlowId(EGRESS_NAT + new IpAddress(new Ipv6Address(IPV6_2)) + "|" + new IpAddress(new Ipv6Address(IPV6_1))), tableId, 80, match, instructionsBuilder.build()).build(); flows.natFlows((short) 6, endpointL3, 80, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperTest.java index a4d577d19..6b53830a8 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperTest.java @@ -50,11 +50,10 @@ public class EgressNatMapperTest extends MapperUtilsTest { EgressNatMapper mapper = new EgressNatMapper(ctx, tableId); // Endpoint - Endpoint endpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0), - new NodeConnectorId(CONNECTOR_1), null, null).build(); + Endpoint endpoint = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_1).build(); // L3 endpoints - EndpointL3 endpointL3 = endpointL3Builder(IPV4_1, IPV4_2, MAC_0, L2, false).build(); + EndpointL3 endpointL3 = buildL3Endpoint(IPV4_0, IPV4_1, MAC_0, L2).build(); List endpointsL3 = new ArrayList<>(); endpointsL3.add(endpointL3); diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapperTest.java index dd7f11627..4a4403b4e 100755 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapperTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/external/ExternalMapperTest.java @@ -8,52 +8,55 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.external; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import com.google.common.collect.ImmutableList; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockOfContext; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.MockEndpointManager; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; -import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.MockSwitchManager; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.Segmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.SegmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import com.google.common.collect.ImmutableSet; - -import java.util.ArrayList; -import java.util.List; + import static org.mockito.Matchers.any; + import static org.mockito.Mockito.mock; + import static org.mockito.Mockito.times; + import static org.mockito.Mockito.verify; + import static org.mockito.Mockito.when; + + import org.junit.Assert; + import org.junit.Before; + import org.junit.Test; + import org.junit.runner.RunWith; + import org.opendaylight.groupbasedpolicy.dto.IndexedTenant; + import org.opendaylight.groupbasedpolicy.dto.PolicyInfo; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockOfContext; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.MockPolicyManager; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.MockEndpointManager; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.MockSwitchManager; + import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager; + import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; + import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; + import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; + import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddressBuilder; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextBuilder; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantBuilder; + import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.ForwardingContextBuilder; + import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; + import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; + import org.powermock.api.mockito.PowerMockito; + import org.powermock.core.classloader.annotations.PrepareForTest; + import org.powermock.modules.junit4.PowerMockRunner; + + import com.google.common.collect.ImmutableSet; + + import java.util.Collection; + import java.util.HashSet; + import java.util.Set; @RunWith(PowerMockRunner.class) @PrepareForTest({PolicyManager.class}) @@ -62,52 +65,21 @@ public class ExternalMapperTest extends MapperUtilsTest { private ExternalMapper mapper; private short tableId; - private NodeId nodeId; - private OfWriter ofWriter; - private MockEndpointManager endpointManagerMock; - private MockPolicyManager policyManagerMock; - private MockSwitchManager switchManagerMock; - private MockOfContext ctxMock; - - private NodeConnectorId nodeConnectorId = new NodeConnectorId("openflow:1:1"); - private MacAddress mac = new MacAddress("00:00:00:00:00:03"); - private NatAddress natAddr = new NatAddressBuilder() - .setNatAddress(new IpAddress(new Ipv4Address("192.168.111.52"))) - .build(); - - private EndpointL3 natL3Ep = new EndpointL3Builder() - .setTenant(tid) - .setL3Context(l3c) - .setMacAddress(mac) - .setL2Context(bd) - .setIpAddress(new IpAddress(new Ipv4Address("10.0.0.3"))) - .addAugmentation(NatAddress.class, natAddr) - .build(); - - private Endpoint l2Ep = new EndpointBuilder() - .setTenant(tid) - .setMacAddress(mac) - .setL2Context(bd) - .setNetworkContainment(ext_sub) - .setEndpointGroup(eg) - .build(); + private Ipv4Address natAddr = new Ipv4Address("192.168.111.52"); + @Before public void initialisation() { PowerMockito.stub(PowerMockito.method(PolicyManager.class, "setSfcTableOffset")).toReturn(true); - endpointManagerMock = new MockEndpointManager(); - policyManagerMock = new MockPolicyManager(endpointManagerMock); - switchManagerMock = new MockSwitchManager(); - ctxMock = new MockOfContext(null, - policyManagerMock, - switchManagerMock, - endpointManagerMock, - null); + endpointManager = mock(EndpointManager.class); + policyManager = mock(PolicyManager.class); + switchManager = mock(SwitchManager.class); + policyInfo = mock(PolicyInfo.class); + ctx = mock(OfContext.class); tableId = 6; - nodeId = mock(NodeId.class); ofWriter = mock(OfWriter.class); - mapper = new ExternalMapper(ctxMock, tableId); + mapper = new ExternalMapper(ctx, tableId); } @Test @@ -117,34 +89,52 @@ public class ExternalMapperTest extends MapperUtilsTest { @Test public void testSync() throws Exception { - SegmentationBuilder segmentationBuilder = new SegmentationBuilder(); - segmentationBuilder.setSegmentationId(1); - List l2FloodDomains = new ArrayList<>(); - L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder(); - l2FloodDomainBuilder.setId(new L2FloodDomainId(ext_fd)); - l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build()); - l2FloodDomains.add(l2FloodDomainBuilder.build()); - ctxMock.addTenant(baseTenantBuilder().setForwardingContext(new ForwardingContextBuilder() - .setL3Context(ImmutableList.of(new L3ContextBuilder().setId(l3c).build())) - .setL2FloodDomain(l2FloodDomains) - .setSubnet(subnet()).build()).build()); - endpointManagerMock.addL3Endpoint(natL3Ep); - l2Ep = new EndpointBuilder(l2Ep) - .addAugmentation(OfOverlayContext.class, new OfOverlayContextBuilder() - .setNodeId(nodeId) - .build()) - .build(); - endpointManagerMock.addEndpoint(l2Ep); - switchManagerMock.addSwitch(nodeId, null, ImmutableSet.of(nodeConnectorId), null); - mapper.sync(l2Ep, ofWriter); + //External Ports + Set externalPorts = new HashSet<>(); + externalPorts.add(Long.valueOf(CONNECTOR_1.getValue())); + // Modified tenant + TenantBuilder tenantBuilder = buildTenant(); + tenantBuilder.setForwardingContext(new ForwardingContextBuilder() + .setL2FloodDomain(getL2FloodDomainList(true)) + .setL2BridgeDomain(getL2BridgeDomainList()) + .setL3Context(getL3ContextList()) + .setSubnet(getSubnetList()).build()) + .build().getId(); + Tenant tenant = tenantBuilder.build(); + // L2 Endpoint + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0) + .setNetworkContainment(L2_FD_ID_EXT) + .setL2Context(L2BD_ID); + // L3 Endpoint with Nat + EndpointL3Builder endpointL3Builder = buildL3Endpoint(natAddr, IPV4_1, MAC_0, null) + .setL2Context(L2BD_ID); + endpointL3Builder.setTenant(tenant.getId()); + Collection l3EndpointsWithNat = new HashSet<>(); + l3EndpointsWithNat.add(endpointL3Builder.build()); + + when(ctx.getTenant(any(TenantId.class))).thenReturn(new IndexedTenant(tenant)); + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getSwitchManager()).thenReturn(switchManager); + when(ctx.getCurrentPolicy()).thenReturn(policyInfo); + when(endpointManager.getEndpointNodeId(any(Endpoint.class))).thenReturn(NODE_ID); + when(endpointManager.getL3EndpointsWithNat()).thenReturn(l3EndpointsWithNat); + when(switchManager.getExternalPortNumbers(any(NodeId.class))).thenReturn(externalPorts); + + mapper.sync(endpointBuilder.build(), ofWriter); + verify(ofWriter, times(4)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class)); } @Test public void testSync_NoExternalPorts() throws Exception { // we still need ExternalMapper flows (default output and default drop) to be generated - ctxMock.addTenant(baseTenantBuilder().build()); - mapper.sync(l2Ep, ofWriter); + EndpointBuilder endpointBuilder = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0); + + when(ctx.getEndpointManager()).thenReturn(endpointManager); + when(ctx.getTenant(any(TenantId.class))).thenReturn(getTestIndexedTenant()); + when(endpointManager.getEndpointNodeId(any(Endpoint.class))).thenReturn(NODE_ID); + + mapper.sync(endpointBuilder.build(), ofWriter); verify(ofWriter, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class)); } -} +} \ No newline at end of file diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlowsTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlowsTest.java index 2608452c9..b16dace4d 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlowsTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlowsTest.java @@ -17,8 +17,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTe import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; @@ -31,10 +29,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4; @@ -51,38 +49,32 @@ import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtil public class IngressNatMapperFlowsTest extends MapperUtilsTest { - private static final String GOTO_DESTINATION_MAPPER = "gotoDestinationMapper"; - private static final String INGRESS_NAT = "IngressNat"; - private static final String INGRESS_ARP = "outside-ip-arp"; - private static final String IN_PORT = ":INPORT"; - private static final String INBOUND_EXTERNAL_IP = "inbound-external-ip"; - private static final String INBOUND_EXTERNAL_ARP = "inbound-external-arp"; private IngressNatMapperFlows flows; @Before - public void init() { + public void init() throws Exception { ctx = mock(OfContext.class); ofWriter = mock(OfWriter.class); endpointManager = mock(EndpointManager.class); policyManager = mock(PolicyManager.class); policyInfo = mock(PolicyInfo.class); tableId = 1; - flows = new IngressNatMapperFlows(nodeId, tableId); + flows = new IngressNatMapperFlows(NODE_ID, tableId); OrdinalFactory.resetPolicyOrdinalValue(); } @Test public void testBaseFlow() { - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(GOTO_DESTINATION_MAPPER), tableId, 50, null, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId("gotoDestinationMapper"), tableId, 50, null, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.baseFlow((short) 2, 50, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testNatFlow_noAugmentation() { - EndpointL3 testEndpointL3 = endpointL3Builder(null, null, null, null, false).build(); + EndpointL3 testEndpointL3 = new EndpointL3Builder().build(); flows.createNatFlow((short) 3, testEndpointL3, null, 60, ofWriter); verifyZeroInteractions(ctx); @@ -91,12 +83,11 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { @Test public void testNatFlow() throws Exception { - EndpointL3 testEndpointL3 = endpointL3Builder(IPV4_1, IPV4_2, null, null, false).build(); - Endpoint testEndpoint = endpointBuilder(null, new MacAddress(MAC_0), - new NodeConnectorId(CONNECTOR_0), null, null).build(); + EndpointL3 testEndpointL3 = buildL3Endpoint(IPV4_0, IPV4_1, MAC_0, null).build(); + Endpoint testEndpoint = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0).build(); when(ctx.getEndpointManager()).thenReturn(endpointManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint); @@ -104,12 +95,12 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { InOrder order = inOrder(ctx); order.verify(ctx, times(1)).getEndpointManager(); order.verify(ctx, times(1)).getCurrentPolicy(); - verify(ctx, times(2)).getTenant(new TenantId(TENANT_ID)); + verify(ctx, times(2)).getTenant(TENANT_ID); assertNotNull(ordinals); List instructions = new ArrayList<>(); - Action[] ipActions = {FlowUtils.setIpv4DstAction(new Ipv4Address(IPV4_2)), - FlowUtils.setDlDstAction(null)}; + Action[] ipActions = {FlowUtils.setIpv4DstAction(new Ipv4Address(IPV4_1)), + FlowUtils.setDlDstAction(new MacAddress(MAC_0))}; Action[] ordinalsAction = {FlowUtils.nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1)), FlowUtils.nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0)), FlowUtils.nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(0)), @@ -123,34 +114,33 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { instructionsBuilder.setInstruction(instructions); MatchBuilder matchBuilder = new MatchBuilder(); - matchBuilder.setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_1 + + matchBuilder.setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build()); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4)); - Flow testFlow = flowBuilder(new FlowId(INGRESS_NAT + "|" + new IpAddress(new Ipv4Address(IPV4_1)).toString() + - "|" + new IpAddress(new Ipv4Address(IPV4_2)).toString() + "|" + "null"), tableId, 60, matchBuilder.build(), - instructionsBuilder.build()).build(); - + Flow testFlow = buildFlow(new FlowId("IngressNat" + "|" + new IpAddress(new Ipv4Address(IPV4_0)).toString() + + "|" + new IpAddress(new Ipv4Address(IPV4_1)).toString() + "|" + new MacAddress(MAC_0)), tableId, + 60, matchBuilder.build(), instructionsBuilder.build()).build(); flows.createNatFlow((short) 2, testEndpointL3, ordinals, 60, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testArpFlow_noAugmentation() { - EndpointL3 testEndpointL3 = endpointL3Builder(null, null, null, null, false).build(); + EndpointL3 testEndpointL3 = new EndpointL3Builder().build(); - flows.createArpFlow(indexedTenantBuilder(), testEndpointL3, 60, ofWriter); + flows.createArpFlow(getTestIndexedTenant(), testEndpointL3, 60, ofWriter); verifyZeroInteractions(ctx); verifyZeroInteractions(ofWriter); } @Test public void testArpFlow() { - EndpointL3 testEndpointL3 = endpointL3Builder(IPV4_1, IPV4_2, MAC_0, null, false).build(); + EndpointL3 testEndpointL3 = buildL3Endpoint(IPV4_0, IPV4_1, MAC_0, null).build(); List instructions = new ArrayList<>(); Action[] arpActions = {nxMoveEthSrcToEthDstAction(), setDlSrcAction(new MacAddress(MAC_0)), nxLoadArpOpAction(BigInteger.valueOf(2L)), nxMoveArpShaToArpThaAction(), nxLoadArpShaAction(new BigInteger("0")), - nxMoveArpSpaToArpTpaAction(), nxLoadArpSpaAction(IPV4_1), outputAction(new NodeConnectorId(NODE_ID + IN_PORT))}; + nxMoveArpSpaToArpTpaAction(), nxLoadArpSpaAction(IPV4_0.getValue()), outputAction(new NodeConnectorId(NODE_ID.getValue() + ":INPORT"))}; instructions.add(new InstructionBuilder().setOrder(0) .setInstruction(FlowUtils.applyActionIns(ArrayUtils.addAll(arpActions))).build()); InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); @@ -158,24 +148,23 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP)); - matchBuilder.setLayer3Match(new ArpMatchBuilder().setArpOp(1).setArpTargetTransportAddress(new Ipv4Prefix(IPV4_1 + matchBuilder.setLayer3Match(new ArpMatchBuilder().setArpOp(1).setArpTargetTransportAddress(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build()); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, INGRESS_ARP, match), + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "outside-ip-arp", match), tableId, 60, match, instructionsBuilder.build()).build(); - flows.createArpFlow(indexedTenantBuilder(), testEndpointL3, 60, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + flows.createArpFlow(getTestIndexedTenant(), testEndpointL3, 60, ofWriter); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testIngressExternalNatFlow() throws Exception { - Endpoint testEndpoint = endpointBuilder(new IpAddress(new Ipv6Address(IPV6_1)), new MacAddress(MAC_0), - new NodeConnectorId(CONNECTOR_0), null, null).build(); + Endpoint testEndpoint = buildEndpoint(IPV4_1, MAC_0, CONNECTOR_0).build(); when(ctx.getEndpointManager()).thenReturn(endpointManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint); @@ -183,7 +172,7 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { InOrder order = inOrder(ctx); order.verify(ctx, times(1)).getEndpointManager(); order.verify(ctx, times(1)).getCurrentPolicy(); - verify(ctx, times(2)).getTenant(new TenantId(TENANT_ID)); + verify(ctx, times(2)).getTenant(TENANT_ID); assertNotNull(ordinals); List instructions = new ArrayList<>(); @@ -200,25 +189,25 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { instructionsBuilder.setInstruction(instructions); MatchBuilder matchBuilder = new MatchBuilder(); - matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6)); - matchBuilder.setLayer3Match(new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(IPV6_1 + IP_PREFIX_128)).build()); + matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4)); + matchBuilder.setLayer3Match(new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(IPV4_1.getValue() + + IP_PREFIX_32)).build()); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, INBOUND_EXTERNAL_IP, match), tableId, 50, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "inbound-external-ip", match), tableId, 50, match, instructionsBuilder.build()).build(); flows.createIngressExternalNatFlows((short) 2, testEndpoint, ordinals, 50, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testIngressExternalArpFlow() throws Exception { - Endpoint testEndpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0), - new NodeConnectorId(CONNECTOR_0), null, null).build(); + Endpoint testEndpoint = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0).build(); when(ctx.getEndpointManager()).thenReturn(endpointManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint); @@ -226,7 +215,7 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { InOrder order = inOrder(ctx); order.verify(ctx, times(1)).getEndpointManager(); order.verify(ctx, times(1)).getCurrentPolicy(); - verify(ctx, times(2)).getTenant(new TenantId(TENANT_ID)); + verify(ctx, times(2)).getTenant(TENANT_ID); assertNotNull(ordinals); List instructions = new ArrayList<>(); @@ -246,11 +235,11 @@ public class IngressNatMapperFlowsTest extends MapperUtilsTest { matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(new MacAddress(MAC_0), null, FlowUtils.ARP)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, INBOUND_EXTERNAL_ARP, match), tableId, 30, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "inbound-external-arp", match), tableId, 30, match, instructionsBuilder.build()).build(); flows.createIngressExternalArpFlows((short) 0, testEndpoint, ordinals, 30, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperTest.java index 09031062b..a82862b71 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperTest.java @@ -22,14 +22,10 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3; -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import java.util.ArrayList; import java.util.HashSet; @@ -40,8 +36,6 @@ import static org.mockito.Mockito.*; public class IngressNatMapperTest extends MapperUtilsTest { - private static final String EPG_ID = "dummy epg id"; - @Before public void init() { ctx = mock(OfContext.class); @@ -56,22 +50,21 @@ public class IngressNatMapperTest extends MapperUtilsTest { public void testSyncFlows() throws Exception { // Endpoints - Endpoint endpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0), - new NodeConnectorId(CONNECTOR_0), null, null).build(); + Endpoint endpoint = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0).build(); List endpoints = new ArrayList<>(); endpoints.add(endpoint); // L3 endpoints - EndpointL3 endpointL3 = endpointL3Builder(IPV4_1, IPV4_2, MAC_0, L2, false).build(); + EndpointL3 endpointL3 = buildL3Endpoint(IPV4_0, IPV4_1, MAC_0, L2).build(); List endpointsL3 = new ArrayList<>(); endpointsL3.add(endpointL3); // EgKEy set Set egKeys = new HashSet<>(); - egKeys.add(new EgKey(new TenantId(TENANT_ID), new EndpointGroupId(EPG_ID))); + egKeys.add(new EgKey(TENANT_ID, ENDPOINT_GROUP_1)); when(ctx.getPolicyManager()).thenReturn(policyManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(ctx.getEndpointManager()).thenReturn(endpointManager); when(endpointManager.getL3EndpointsWithNat()).thenReturn(endpointsL3); when(endpointManager.getEndpoint(Mockito.any(EpKey.class))).thenReturn(endpoint); diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/policyenforcer/PolicyEnforcerTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/policyenforcer/PolicyEnforcerTest.java index fc2f5c733..ca6c6eb9f 100755 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/policyenforcer/PolicyEnforcerTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/policyenforcer/PolicyEnforcerTest.java @@ -41,7 +41,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.MockSwitchManag import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName; @@ -51,6 +50,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayNodeConfigBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.nodes.node.TunnelBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction; @@ -102,27 +102,27 @@ public class PolicyEnforcerTest extends MapperUtilsTest { private final int allowTunnelFlows = 1; private final int layer4flowsIPv4 = 1; private final int layer4flowsIPv6 = 1; - private final int dropAllFlow = 1; - private final int arpFlows = 1; - private MockEndpointManager endpointManagerMock; - private MockPolicyManager policyManagerMock; - private MockSwitchManager switchManagerMock; - private MockOfContext ctxMock; + private static final String TCP_DST = "tcp_dst_80"; private NodeConnectorId tunnelId = - new NodeConnectorId(nodeId.getValue() + ":42"); + new NodeConnectorId(NODE_ID.getValue() + ":42"); + private NodeConnectorId nodeConnector = new NodeConnectorId(NODE_ID.getValue() + CONNECTOR_0); @Before public void setup() throws Exception { PowerMockito.stub(PowerMockito.method(PolicyManager.class, "setSfcTableOffset")).toReturn(true); - endpointManagerMock = new MockEndpointManager(); - policyManagerMock = new MockPolicyManager(endpointManagerMock); - switchManagerMock = new MockSwitchManager(); - ctxMock = new MockOfContext(null, policyManagerMock, switchManagerMock, endpointManagerMock, null); - table = new PolicyEnforcer(ctxMock, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()); + endpointManager = new MockEndpointManager(); + policyManager = new MockPolicyManager(endpointManager); + switchManager = new MockSwitchManager(); + ctx = new MockOfContext(null, + policyManager, + switchManager, + endpointManager, + null); + table = new PolicyEnforcer(ctx, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()); - switchManagerMock.addSwitch( - nodeId, + ((MockSwitchManager)switchManager).addSwitch( + NODE_ID, tunnelId, Collections.emptySet(), new OfOverlayNodeConfigBuilder().setTunnel( @@ -134,31 +134,35 @@ public class PolicyEnforcerTest extends MapperUtilsTest { @Test public void testSameEg() throws Exception { - Endpoint ep1 = endpointBuilder(new IpAddress(IPV4_1.toCharArray()), new MacAddress(MAC_0), nodeConnectorId, eg, bd) - .build(); - endpointManagerMock.addEndpoint(ep1); - Endpoint ep2 = endpointBuilder(new IpAddress(IPV4_2.toCharArray()), new MacAddress(MAC_1), nodeConnectorId, eg, bd) - .build(); - endpointManagerMock.addEndpoint(ep2); - ctxMock.addTenant(baseTenantBuilder().setPolicy(new PolicyBuilder(baseTenantBuilder().getPolicy()) + EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector); + ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0); + ep1Builder.setL2Context(L2BD_ID); + Endpoint ep1 = ep1Builder.build(); + ((MockEndpointManager)endpointManager).addEndpoint(ep1); + EndpointBuilder ep2Builder = buildEndpoint(IPV4_1,MAC_1, nodeConnector); + ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1); + ep2Builder.setL2Context(L2BD_ID); + Endpoint ep2 = ep2Builder.build(); + ((MockEndpointManager)endpointManager).addEndpoint(ep2); + ((MockOfContext)ctx).addTenant(buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy()) .setContract(ImmutableList.of(baseContract(null).build())).build()).build()); ofWriter = new OfWriter(); table.sync(ep1, ofWriter); - assertTrue(!ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()) + assertTrue(!ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()) .getFlow() .isEmpty()); int count = 0; HashMap flowMap = new HashMap<>(); - for (Flow f : ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) { + for (Flow f : ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) { flowMap.put(f.getId().getValue(), f); if (isAllowSameEpg(f)) { count += 1; } } assertEquals(sameEpgFlows, count); - int totalFlows = sameEpgFlows + allowTunnelFlows + dropAllFlow; - assertEquals(totalFlows, ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()) + int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6; + assertEquals(totalFlows, ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()) .getFlow() .size()); } @@ -178,27 +182,27 @@ public class PolicyEnforcerTest extends MapperUtilsTest { @Test public void doTestRule() throws Exception { Rule rule1 = new RuleBuilder().setActionRef( - ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build())) + ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build())) .setClassifierRef( - createClassifierRefs(ImmutableMap.of("tcp_dst_80", Direction.In, "tcp_src_80", + createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.In))) .build(); Rule rule2 = new RuleBuilder().setActionRef( - ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build())) + ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build())) .setClassifierRef( - createClassifierRefs(ImmutableMap.of("tcp_dst_80", Direction.In, "tcp_src_80", + createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out))) .build(); Rule rule3 = new RuleBuilder().setActionRef( - ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build())) + ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build())) .setClassifierRef( - createClassifierRefs(ImmutableMap.of("tcp_dst_80", Direction.In, "tcp_src_80", + createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, TCP_SRC, Direction.Out, "ether_type", Direction.In))) .build(); Rule rule4 = new RuleBuilder().setActionRef( - ImmutableList.of(new ActionRefBuilder().setName(new ActionName("allow")).build())) + ImmutableList.of(new ActionRefBuilder().setName(new ActionName(ALLOW)).build())) .setClassifierRef( - createClassifierRefs(ImmutableMap.of("tcp_dst_80", Direction.In, "tcp_dst_90", + createClassifierRefs(ImmutableMap.of(TCP_DST, Direction.In, "tcp_dst_90", Direction.In))) .build(); @@ -219,22 +223,26 @@ public class PolicyEnforcerTest extends MapperUtilsTest { } private int doTestDifferentEg(List subjects) throws Exception { - Endpoint ep1 = endpointBuilder(new IpAddress(IPV4_1.toCharArray()), new MacAddress(MAC_0), nodeConnectorId, eg, bd) - .build(); - endpointManagerMock.addEndpoint(ep1); - Endpoint ep2 = endpointBuilder(new IpAddress(IPV4_2.toCharArray()), new MacAddress(MAC_1), nodeConnectorId, eg2, bd) - .build(); - endpointManagerMock.addEndpoint(ep2); - ctxMock.addTenant(baseTenantBuilder().setPolicy(new PolicyBuilder(baseTenantBuilder().getPolicy()) + EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector); + ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0); + ep1Builder.setL2Context(L2BD_ID); + Endpoint ep1 = ep1Builder.build(); + ((MockEndpointManager)endpointManager).addEndpoint(ep1); + EndpointBuilder ep2Builder = buildEndpoint(IPV4_1, MAC_1, nodeConnector); + ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1); + ep2Builder.setL2Context(L2BD_ID); + Endpoint ep2 = ep2Builder.build(); + ((MockEndpointManager)endpointManager).addEndpoint(ep2); + ((MockOfContext)ctx).addTenant(buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy()) .setContract(ImmutableList.of(baseContract(subjects).build())).build()).build()); ofWriter = new OfWriter(); table.sync(ep1, ofWriter); - assertTrue(!ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()) + assertTrue(!ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()) .getFlow() .isEmpty()); int count = 0; - for (Flow f : ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) { + for (Flow f : ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) { if (isAllowSameEpg(f)) { count += 1; } else if (f.getMatch() != null && Objects.equals(tunnelId, f.getMatch().getInPort())) { @@ -280,16 +288,21 @@ public class PolicyEnforcerTest extends MapperUtilsTest { Condition cond1 = new ConditionBuilder().setName(new ConditionName("cond1")).build(); Condition cond2 = new ConditionBuilder().setName(new ConditionName("cond2")).build(); - Endpoint ep1 = endpointBuilder(new IpAddress(IPV4_1.toCharArray()), new MacAddress(MAC_0), nodeConnectorId, eg, bd) - .setCondition(ImmutableList.of(cond1.getName())).build(); - endpointManagerMock.addEndpoint(ep1); - Endpoint ep2 = endpointBuilder(new IpAddress(IPV4_2.toCharArray()), new MacAddress(MAC_1), nodeConnectorId, eg2, bd) - .setCondition(ImmutableList.of(cond1.getName(), cond2.getName())) - .build(); - endpointManagerMock.addEndpoint(ep2); + EndpointBuilder ep1Builder = buildEndpoint(IPV4_0, MAC_0, nodeConnector); + ep1Builder.setEndpointGroup(ENDPOINT_GROUP_0); + ep1Builder.setL2Context(L2BD_ID); + ep1Builder.setCondition(ImmutableList.of(cond1.getName())).build(); + Endpoint ep1 = ep1Builder.build(); + ((MockEndpointManager)endpointManager).addEndpoint(ep1); + EndpointBuilder ep2Builder = buildEndpoint(IPV4_1,MAC_1, nodeConnector); + ep2Builder.setEndpointGroup(ENDPOINT_GROUP_1); + ep2Builder.setL2Context(L2BD_ID); + ep2Builder.setCondition(ImmutableList.of(cond1.getName(), cond2.getName())).build(); + Endpoint ep2 = ep2Builder.build(); + ((MockEndpointManager)endpointManager).addEndpoint(ep2); - TenantBuilder tb = baseTenantBuilder().setPolicy(new PolicyBuilder(baseTenantBuilder().getPolicy()).setContract( - ImmutableList.of(new ContractBuilder().setId(cid) + TenantBuilder tb = buildTenant().setPolicy(new PolicyBuilder(buildTenant().getPolicy()).setContract( + ImmutableList.of(new ContractBuilder().setId(CONTRACT_ID) .setSubject(ImmutableList.of(baseSubject(Direction.Out).build())) .setClause( ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test")) @@ -310,12 +323,12 @@ public class PolicyEnforcerTest extends MapperUtilsTest { .build())).build()) .build())) .build())).build()); - ctxMock.addTenant(tb.build()); + ((MockOfContext)ctx).addTenant(tb.build()); - PolicyInfo policy = ctxMock.getCurrentPolicy(); - List ep1c = endpointManagerMock.getConditionsForEndpoint(ep1); + PolicyInfo policy = ctx.getCurrentPolicy(); + List ep1c = endpointManager.getConditionsForEndpoint(ep1); ConditionGroup cg1 = policy.getEgCondGroup(new EgKey(tb.getId(), ep1.getEndpointGroup()), ep1c); - List ep2c = endpointManagerMock.getConditionsForEndpoint(ep2); + List ep2c = endpointManager.getConditionsForEndpoint(ep2); ConditionGroup cg2 = policy.getEgCondGroup(new EgKey(tb.getId(), ep2.getEndpointGroup()), ep2c); int cg1Id = OrdinalFactory.getCondGroupOrdinal(cg1); int cg2Id = OrdinalFactory.getCondGroupOrdinal(cg2); @@ -332,12 +345,14 @@ public class PolicyEnforcerTest extends MapperUtilsTest { ofWriter = new OfWriter(); table.sync(ep1, ofWriter); // one layer4 flow for each direction - int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6 + arpFlows + dropAllFlow;; - assertEquals(totalFlows, ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()) + int dropAllFlow = 1; + int arpFlows = 1; + int totalFlows = sameEpgFlows + allowTunnelFlows + layer4flowsIPv4 + layer4flowsIPv6 + arpFlows + dropAllFlow; + assertEquals(totalFlows, ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()) .getFlow() .size()); HashMap flowMap = new HashMap<>(); - for (Flow f : ofWriter.getTableForNode(nodeId, ctxMock.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) { + for (Flow f : ofWriter.getTableForNode(NODE_ID, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()).getFlow()) { flowMap.put(f.getId().getValue(), f); if (f.getMatch() != null && f.getMatch().getEthernetMatch() != null) { count++; @@ -384,11 +399,11 @@ public class PolicyEnforcerTest extends MapperUtilsTest { } protected ContractBuilder baseContract(List subjects) { - ContractBuilder contractBuilder = new ContractBuilder().setId(cid).setSubject(subjects); + ContractBuilder contractBuilder = new ContractBuilder().setId(CONTRACT_ID).setSubject(subjects); // TODO refactor if (subjects == null) { return contractBuilder.setClause(ImmutableList.of(new ClauseBuilder().setName(new ClauseName("test")) - .setSubjectRefs(ImmutableList.of(new SubjectName("s1"))) + .setSubjectRefs(ImmutableList.of(new SubjectName("s1"))) .build())); } List subjectNames = new ArrayList<>(); @@ -405,12 +420,12 @@ public class PolicyEnforcerTest extends MapperUtilsTest { .setName(new SubjectName("s1")) .setRule(ImmutableList.of(new RuleBuilder() .setActionRef(ImmutableList.of(new ActionRefBuilder() - .setName(new ActionName("allow")) + .setName(new ActionName(ALLOW)) .build())) .setClassifierRef(ImmutableList.of(new ClassifierRefBuilder() - .setName(new ClassifierName("tcp_dst_80")) + .setName(new ClassifierName(TCP_DST)) .setDirection(direction) - .setInstanceName(new ClassifierName("tcp_dst_80")) + .setInstanceName(new ClassifierName(TCP_DST)) .build())) .build())); } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityFlowsTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityFlowsTest.java index e4d7e45e6..76fc292e2 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityFlowsTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityFlowsTest.java @@ -9,7 +9,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTe import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; @@ -33,28 +32,23 @@ import static org.mockito.Mockito.*; public class PortSecurityFlowsTest extends MapperUtilsTest { - private static final String DROP_ALL = "dropAll"; - private static final String DROP = "drop"; - private static final String ALLOW = "allow"; private static final String L3 = "L3"; private static final String DHCP = "dhcp"; - private static final String ALLOW_EXTERNAL = "allowExternal"; - private static final String ALLOW_EXTERNAL_POP_VLAN = "allowExternalPopVlan"; private PortSecurityFlows flows; @Before public void init() { tableId = 0; ofWriter = mock(OfWriter.class); - flows = new PortSecurityFlows(nodeId, tableId); + flows = new PortSecurityFlows(NODE_ID, tableId); } @Test public void testDropFlow_noEthertype() { - Flow testFlow = flowBuilder(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build(); + Flow testFlow = buildFlow(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, null, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -62,11 +56,11 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.IPv4, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -74,11 +68,11 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.IPv6, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -86,11 +80,11 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.ARP, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -99,11 +93,11 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setInPort(new NodeConnectorId(String.valueOf(VXLAN_PORT))); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, ALLOW, match), tableId, 300, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, ALLOW, match), tableId, 300, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.allowFromTunnelFlow((short) 2, 300, new NodeConnectorId(CONNECTOR_0), ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @@ -113,83 +107,71 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setInPort(new NodeConnectorId(String.valueOf(VXLAN_PORT))); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, ALLOW, match), tableId, 300, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, ALLOW, match), tableId, 300, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.allowFromTunnelFlow((short) 2, 300, new NodeConnectorId(CONNECTOR_1), ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testL3flow_ipv4() { - IpAddress ipAddress = new IpAddress(new Ipv4Address(IPV4_1)); - MacAddress macAddress = new MacAddress(MAC_0); - NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_0); - Endpoint testEp = endpointBuilder(ipAddress, macAddress, connectorId, null, null).build(); + Endpoint testEp = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0).build(); MatchBuilder matchBuilder = new MatchBuilder(); - matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(macAddress, null, FlowUtils.IPv4)) + matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(MAC_0, null, FlowUtils.IPv4)) .setLayer3Match(new Ipv4MatchBuilder() - .setIpv4Source(new Ipv4Prefix(ipAddress.getIpv4Address().getValue() + IP_PREFIX_32)).build()) - .setInPort(connectorId); + .setIpv4Source(new Ipv4Prefix(IPV4_0.getValue() + IP_PREFIX_32)).build()) + .setInPort(new NodeConnectorId(CONNECTOR_0)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.l3Flow((short) 2, testEp, new NodeConnectorId(CONNECTOR_0), new MacAddress(MAC_0), 100, false, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testL3flow_ipv4Arp() { - IpAddress ipAddress = new IpAddress(new Ipv4Address(IPV4_1)); - MacAddress macAddress = new MacAddress(MAC_1); - NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_1); - Endpoint testEp = endpointBuilder(ipAddress, macAddress, connectorId, null, null).build(); + Endpoint testEp = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1).build(); MatchBuilder matchBuilder = new MatchBuilder(); - matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(macAddress, null, FlowUtils.ARP)) - .setLayer3Match(new ArpMatchBuilder().setArpSourceTransportAddress(new Ipv4Prefix(ipAddress - .getIpv4Address().getValue() + IP_PREFIX_32)).build()) - .setInPort(connectorId); + matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(MAC_1, null, FlowUtils.ARP)) + .setLayer3Match(new ArpMatchBuilder().setArpSourceTransportAddress(new Ipv4Prefix(IPV4_0.getValue() + + IP_PREFIX_32)).build()) + .setInPort(new NodeConnectorId(CONNECTOR_1)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.l3Flow((short) 2, testEp, new NodeConnectorId(CONNECTOR_1), new MacAddress(MAC_1), 100, true, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testL3flow_ipv6() { - IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1)); - MacAddress macAddress = new MacAddress(MAC_0); - NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_0); - Endpoint testEp = endpointBuilder(ipAddress, macAddress, connectorId, null, null).build(); + Endpoint testEp = buildEndpoint(IPV6_1, MAC_0, CONNECTOR_0).build(); MatchBuilder matchBuilder = new MatchBuilder(); - matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(macAddress, null, FlowUtils.IPv6)) + matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(MAC_0, null, FlowUtils.IPv6)) .setLayer3Match(new Ipv6MatchBuilder() - .setIpv6Source(new Ipv6Prefix(ipAddress.getIpv6Address().getValue() + IP_PREFIX_128)).build()) - .setInPort(connectorId); + .setIpv6Source(new Ipv6Prefix(IPV6_1.getValue() + IP_PREFIX_128)).build()) + .setInPort(new NodeConnectorId(CONNECTOR_0)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.l3Flow((short) 2, testEp, new NodeConnectorId(CONNECTOR_0), new MacAddress(MAC_0), 100, false, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void testL3flow_ipv6Arp() { - IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1)); - MacAddress macAddress = new MacAddress(MAC_1); - NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_1); - Endpoint testEp = endpointBuilder(ipAddress, macAddress, connectorId, null, null).build(); + Endpoint testEp = buildEndpoint(IPV6_1, MAC_1, CONNECTOR_1).build(); flows.l3Flow((short) 2, testEp, new NodeConnectorId(CONNECTOR_1), new MacAddress(MAC_1), 100, true, ofWriter); verifyZeroInteractions(ofWriter); @@ -197,7 +179,7 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { @Test public void testL3DhcpDoraFlow() { - IpAddress ipAddress = new IpAddress(new Ipv4Address(DHCP_IP)); + IpAddress ipAddress = new IpAddress(new Ipv4Address("255.255.255.255")); MacAddress macAddress = new MacAddress(MAC_1); NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_1); @@ -208,11 +190,11 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { .setInPort(connectorId); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DHCP, match), tableId, 50, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DHCP, match), tableId, 50, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.l3DhcpDoraFlow((short) 2, new NodeConnectorId(CONNECTOR_1), new MacAddress(MAC_1), 50, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -225,11 +207,11 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { .setInPort(connectorId); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, L2, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, L2, match), tableId, 100, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.l2flow((short) 2, new NodeConnectorId(CONNECTOR_0), new MacAddress(MAC_0), 100, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -248,13 +230,13 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { InstructionsBuilder instructionsBuilder = new InstructionsBuilder(); instructionsBuilder.setInstruction(instructions); - List l2FloodDomains = l2FloodDomains(); + List l2FloodDomains = getL2FloodDomainList(false); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, ALLOW_EXTERNAL_POP_VLAN, match), tableId, 200, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "allowExternalPopVlan", match), tableId, 200, match, instructionsBuilder.build()).build(); flows.popVlanTagsOnExternalPortFlows((short) 0, connectorId, l2FloodDomains, 200, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -265,9 +247,9 @@ public class PortSecurityFlowsTest extends MapperUtilsTest { matchBuilder.setInPort(connectorId); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, ALLOW_EXTERNAL, match), tableId, 250, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "allowExternal", match), tableId, 250, match, FlowUtils.gotoTableInstructions((short) 2)).build(); flows.allowFromExternalPortFlow((short) 2, connectorId, 250, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityTest.java index aecfa3ae8..eb4ea9de0 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityTest.java @@ -10,8 +10,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; @@ -31,6 +29,7 @@ public class PortSecurityTest extends MapperUtilsTest { @Before public void init() { ctx = mock(OfContext.class); + tableId = 1; policyManager = mock(PolicyManager.class); switchManager = mock(SwitchManager.class); endpointManager = mock(EndpointManager.class); @@ -39,34 +38,30 @@ public class PortSecurityTest extends MapperUtilsTest { @Test public void testSyncFlows() throws Exception { - Short tableId = 0; - IpAddress ipAddress = new IpAddress(new Ipv4Address(IPV4_1)); - MacAddress macAddress = new MacAddress(MAC_0); - NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_0); // Node connectors Set connectors = new HashSet<>(); connectors.add(new NodeConnectorId(CONNECTOR_0)); // Prepare endpoint - EndpointBuilder endpointBuilder = new EndpointBuilder(endpointBuilder(ipAddress, macAddress, connectorId, - null, null).build()); - endpointBuilder.setTenant(indexedTenantBuilder().getTenant().getId()); + EndpointBuilder endpointBuilder = new EndpointBuilder(buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0) + .build()); + endpointBuilder.setTenant(getTestIndexedTenant().getTenant().getId()); Endpoint endpoint = endpointBuilder.build(); when(ctx.getEndpointManager()).thenReturn(endpointManager); when(ctx.getSwitchManager()).thenReturn(switchManager); when(ctx.getPolicyManager()).thenReturn(policyManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(endpointManager.getEndpointNodeConnectorId(Mockito.any(Endpoint.class))) .thenReturn(new NodeConnectorId(CONNECTOR_0)); - when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(new NodeConnectorId(CONNECTOR_0)); - when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlanGpe.class)).thenReturn(new NodeConnectorId(CONNECTOR_1)); + when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlan.class)).thenReturn(new NodeConnectorId(CONNECTOR_0)); + when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlanGpe.class)).thenReturn(new NodeConnectorId(CONNECTOR_1)); when(switchManager.getExternalPorts(Mockito.any(NodeId.class))).thenReturn(connectors); PortSecurityFlows flows = mock(PortSecurityFlows.class); PortSecurity portSecurity = new PortSecurity(ctx, tableId); - portSecurity.syncFlows(flows, nodeId, endpoint, ofWriter); + portSecurity.syncFlows(flows, NODE_ID, endpoint, ofWriter); // Verify usage verify(flows, times(4)).dropFlow(Mockito.anyInt(), Mockito.anyLong(), eq(ofWriter)); @@ -81,7 +76,7 @@ public class PortSecurityTest extends MapperUtilsTest { verify(flows, times(1)).l2flow(Mockito.anyShort(), Mockito.any(NodeConnectorId.class), Mockito.any(MacAddress.class), Mockito.anyInt(), eq(ofWriter)); verify(flows, times(1)).popVlanTagsOnExternalPortFlows(Mockito.anyShort(), Mockito.any(NodeConnectorId.class), - eq(l2FloodDomains()), Mockito.anyInt(), eq(ofWriter)); + eq(getL2FloodDomainList(false)), Mockito.anyInt(), eq(ofWriter)); verify(flows, times(1)).allowFromExternalPortFlow(Mockito.anyShort(), Mockito.any(NodeConnectorId.class), Mockito.anyInt(), eq(ofWriter)); @@ -108,7 +103,7 @@ public class PortSecurityTest extends MapperUtilsTest { order.verify(ctx, times(1)).getSwitchManager(); order.verify(ctx, times(2)).getTenant(Mockito.any(TenantId.class)); order.verify(flows, times(1)).popVlanTagsOnExternalPortFlows(Mockito.anyShort(), Mockito.any(NodeConnectorId.class), - eq(l2FloodDomains()), Mockito.anyInt(), eq(ofWriter)); + eq(getL2FloodDomainList(false)), Mockito.anyInt(), eq(ofWriter)); order.verify(flows, times(1)).allowFromExternalPortFlow(Mockito.anyShort(), Mockito.any(NodeConnectorId.class), Mockito.anyInt(), eq(ofWriter)); } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperFlowsTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperFlowsTest.java index eccef1cb7..ebf4480d0 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperFlowsTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperFlowsTest.java @@ -12,8 +12,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; @@ -32,11 +30,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; -import java.lang.reflect.Field; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.*; @@ -44,11 +40,6 @@ import static org.mockito.Mockito.*; public class SourceMapperFlowsTest extends MapperUtilsTest { - private static final String DROP = "drop"; - private static final String DROP_ALL = "dropAll"; - private static final String TUNNEL = "tunnel"; - private static final String FLOOD_ID = "tunnelFdId"; - private SourceMapperFlows flows; @Before @@ -58,16 +49,16 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { endpointManager = mock(EndpointManager.class); policyInfo = mock(PolicyInfo.class); ofWriter = mock(OfWriter.class); - flows = new SourceMapperFlows(nodeId, tableId); + flows = new SourceMapperFlows(NODE_ID, tableId); OrdinalFactory.resetPolicyOrdinalValue(); } @Test public void dropFlow_noEthertype() { - Flow testFlow = flowBuilder(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build(); + Flow testFlow = buildFlow(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, null, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -75,11 +66,11 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.IPv4, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -87,11 +78,11 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.IPv6, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test @@ -99,20 +90,19 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match, FlowUtils.dropInstructions()).build(); flows.dropFlow(100, FlowUtils.ARP, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void synchronizeEp() throws Exception { - Endpoint testEndpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_1), - new NodeConnectorId(CONNECTOR_1), null, null).build(); + Endpoint testEndpoint = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_1).build(); when(ctx.getEndpointManager()).thenReturn(endpointManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint); @@ -120,7 +110,7 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { InOrder order = inOrder(ctx); order.verify(ctx, times(1)).getEndpointManager(); order.verify(ctx, times(1)).getCurrentPolicy(); - verify(ctx, times(2)).getTenant(new TenantId(TENANT_ID)); + verify(ctx, times(2)).getTenant(TENANT_ID); assertNotNull(ordinals); Action reg0 = FlowUtils.nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1)); @@ -145,20 +135,19 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { .setInPort(new NodeConnectorId(CONNECTOR_1)); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, "ep", match), tableId, 90, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "ep", match), tableId, 90, match, instructionsBuilder.build()).build(); flows.synchronizeEp((short) 3, 90, ordinals, new MacAddress(MAC_1), new NodeConnectorId(CONNECTOR_1), ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void createTunnelFlow() throws Exception { - Endpoint testEndpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0), - new NodeConnectorId(CONNECTOR_0), null, null).build(); + Endpoint testEndpoint = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_0).build(); when(ctx.getEndpointManager()).thenReturn(endpointManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint); @@ -166,7 +155,7 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { InOrder order = inOrder(ctx); order.verify(ctx, times(1)).getEndpointManager(); order.verify(ctx, times(1)).getCurrentPolicy(); - verify(ctx, times(2)).getTenant(new TenantId(TENANT_ID)); + verify(ctx, times(2)).getTenant(TENANT_ID); assertNotNull(ordinals); Action reg0 = FlowUtils.nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1)); @@ -189,20 +178,19 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { FlowUtils.addNxTunIdMatch(matchBuilder, 2); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, TUNNEL, match), tableId, 80, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "tunnel", match), tableId, 80, match, instructionsBuilder.build()).build(); flows.createTunnelFlow((short) 3, 80, new NodeConnectorId(CONNECTOR_0), ordinals, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } @Test public void createBroadcastFlow() throws Exception { - Endpoint testEndpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0), - new NodeConnectorId(CONNECTOR_1), null, null).build(); + Endpoint testEndpoint = buildEndpoint(IPV4_0, MAC_0, CONNECTOR_1).build(); when(ctx.getEndpointManager()).thenReturn(endpointManager); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint); @@ -210,7 +198,7 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { InOrder order = inOrder(ctx); order.verify(ctx, times(1)).getEndpointManager(); order.verify(ctx, times(1)).getCurrentPolicy(); - verify(ctx, times(2)).getTenant(new TenantId(TENANT_ID)); + verify(ctx, times(2)).getTenant(TENANT_ID); assertNotNull(ordinals); Action reg5 = FlowUtils.nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0)); @@ -229,10 +217,10 @@ public class SourceMapperFlowsTest extends MapperUtilsTest { FlowUtils.addNxTunIdMatch(matchBuilder, 0); Match match = matchBuilder.build(); - Flow testFlow = flowBuilder(FlowIdUtils.newFlowId(tableId, FLOOD_ID, match), tableId, 80, match, + Flow testFlow = buildFlow(FlowIdUtils.newFlowId(tableId, "tunnelFdId", match), tableId, 80, match, instructionsBuilder.build()).build(); flows.createBroadcastFlow((short) 3, 80, new NodeConnectorId(CONNECTOR_1), ordinals, ofWriter); - verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow); + verify(ofWriter, times(1)).writeFlow(NODE_ID, tableId, testFlow); } } \ No newline at end of file diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperTest.java index 9a093addd..0b61f1899 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/source/SourceMapperTest.java @@ -13,8 +13,6 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointMan import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.MapperUtilsTest; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; @@ -47,27 +45,25 @@ public class SourceMapperTest extends MapperUtilsTest { @Test public void syncFlows_tunnelPortTest() { - Endpoint endpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_1), - new NodeConnectorId(CONNECTOR_0), null, null).build(); + Endpoint endpoint = buildEndpoint(IPV4_0, MAC_1, CONNECTOR_0).build(); EndpointBuilder endpointBuilder = new EndpointBuilder(endpoint); - endpointBuilder.setEndpointGroup(new EndpointGroupId(EPG_ID)); + endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_1); // List of other endpoints (one entry is good enough) HashSet otherEndpoints = new HashSet<>(); - Endpoint otherEndpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_2)), new MacAddress(MAC_1), - new NodeConnectorId(CONNECTOR_1), null, null).build(); + Endpoint otherEndpoint = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1).build(); EndpointBuilder otherEndpointBuilder = new EndpointBuilder(otherEndpoint); - otherEndpointBuilder.setEndpointGroup(new EndpointGroupId(ENDPOINT_GROUP_0)); + otherEndpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0); List endpointGroupIds = new ArrayList<>(); - endpointGroupIds.add(new EndpointGroupId(ENDPOINT_GROUP_1)); - endpointGroupIds.add(new EndpointGroupId(ENDPOINT_GROUP_2)); + endpointGroupIds.add(ENDPOINT_GROUP_1); + endpointGroupIds.add(ENDPOINT_GROUP_2); otherEndpointBuilder.setEndpointGroups(endpointGroupIds); otherEndpoints.add(otherEndpointBuilder.build()); // NodeId set Set nodeIds = new HashSet<>(); - nodeIds.add(nodeId); - nodeIds.add(new NodeId("some Id")); + nodeIds.add(NODE_ID); + nodeIds.add(new NodeId("someNodeId")); SourceMapper sourceMapper = new SourceMapper(ctx, tableId); @@ -75,20 +71,20 @@ public class SourceMapperTest extends MapperUtilsTest { when(ctx.getSwitchManager()).thenReturn(switchManager); when(ctx.getEndpointManager()).thenReturn(endpointManager); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(policyManager.getTABLEID_DESTINATION_MAPPER()).thenReturn((short) 3); - when(switchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class)).thenReturn(new NodeConnectorId(CONNECTOR_1)); + when(switchManager.getTunnelPort(NODE_ID, TunnelTypeVxlan.class)).thenReturn(new NodeConnectorId(CONNECTOR_1)); when(endpointManager.getEndpointsForGroup(Mockito.any(EgKey.class))).thenReturn(otherEndpoints); SourceMapperFlows flows = mock(SourceMapperFlows.class); - sourceMapper.syncFlows(flows, endpointBuilder.build(), nodeId, ofWriter); + sourceMapper.syncFlows(flows, endpointBuilder.build(), NODE_ID, ofWriter); // Verify method usage verify(ctx, times(3)).getEndpointManager(); verify(ctx, times(5)).getTenant(Mockito.any(TenantId.class)); verify(ctx.getPolicyManager(), times(1)).getTABLEID_DESTINATION_MAPPER(); - verify(ctx.getSwitchManager(), times(1)).getTunnelPort(nodeId, TunnelTypeVxlan.class); + verify(ctx.getSwitchManager(), times(1)).getTunnelPort(NODE_ID, TunnelTypeVxlan.class); verify(ctx.getEndpointManager(), times(1)).getEndpointsForGroup(Mockito.any(EgKey.class)); // Verify order @@ -108,13 +104,12 @@ public class SourceMapperTest extends MapperUtilsTest { @Test public void syncFlows_endpointGroupsOnly() { - Endpoint endpoint = endpointBuilder(new IpAddress(new Ipv4Address(IPV4_2)), new MacAddress(MAC_1), - new NodeConnectorId(CONNECTOR_1), null, null).build(); + Endpoint endpoint = buildEndpoint(IPV4_1, MAC_1, CONNECTOR_1).build(); EndpointBuilder endpointBuilder = new EndpointBuilder(endpoint); - endpointBuilder.setEndpointGroup(new EndpointGroupId(ENDPOINT_GROUP_0)); + endpointBuilder.setEndpointGroup(ENDPOINT_GROUP_0); List endpointGroupIds = new ArrayList<>(); - endpointGroupIds.add(new EndpointGroupId(ENDPOINT_GROUP_1)); - endpointGroupIds.add(new EndpointGroupId(ENDPOINT_GROUP_2)); + endpointGroupIds.add(ENDPOINT_GROUP_1); + endpointGroupIds.add(ENDPOINT_GROUP_2); endpointBuilder.setEndpointGroups(endpointGroupIds); SourceMapper sourceMapper = new SourceMapper(ctx, tableId); @@ -123,17 +118,17 @@ public class SourceMapperTest extends MapperUtilsTest { when(ctx.getSwitchManager()).thenReturn(switchManager); when(ctx.getEndpointManager()).thenReturn(endpointManager); when(ctx.getCurrentPolicy()).thenReturn(policyInfo); - when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(indexedTenantBuilder()); + when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(getTestIndexedTenant()); when(policyManager.getTABLEID_DESTINATION_MAPPER()).thenReturn((short) 3); SourceMapperFlows flows = mock(SourceMapperFlows.class); - sourceMapper.syncFlows(flows, endpointBuilder.build(), nodeId, ofWriter); + sourceMapper.syncFlows(flows, endpointBuilder.build(), NODE_ID, ofWriter); // Verify OfContext method usage verify(ctx, times(3)).getTenant(Mockito.any(TenantId.class)); verify(ctx.getPolicyManager(), times(1)).getTABLEID_DESTINATION_MAPPER(); - verify(ctx.getSwitchManager(), times(1)).getTunnelPort(nodeId, TunnelTypeVxlan.class); + verify(ctx.getSwitchManager(), times(1)).getTunnelPort(NODE_ID, TunnelTypeVxlan.class); // Verify order InOrder order = inOrder(ctx, flows); -- 2.36.6