OfOverlayRefactoring - IngressNatMapper + EgressNatMapper 79/35579/13
authorVladimir Lavor <vlavor@cisco.com>
Mon, 14 Mar 2016 11:24:27 +0000 (12:24 +0100)
committerVladimir Lavor <vlavor@cisco.com>
Wed, 16 Mar 2016 13:23:52 +0000 (14:23 +0100)
Signed-off-by: Vladimir Lavor <vlavor@cisco.com>
Change-Id: I440899c04f5d4dc1c9885bed5f2613e775dfbeba

15 files changed:
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/endpoint/EndpointManager.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlows.java [new file with mode: 0644]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapper.java
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlows.java [new file with mode: 0644]
renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityFlows.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/EgressNatMapperTest.java [deleted file]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/IngressNatMapperTest.java [deleted file]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/MapperUtilsTest.java [new file with mode: 0644]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlowsTest.java [new file with mode: 0644]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperTest.java [new file with mode: 0644]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlowsTest.java [new file with mode: 0644]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperTest.java [new file with mode: 0644]
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityFlowsTest.java
renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/portsecurity/PortSecurityTest.java

index 551bfff11e2136bd0d98fce5bdca6d67f753d194..d29ccc6e0e52d277992e5878b65cedcd0ce95ff3 100755 (executable)
@@ -8,9 +8,6 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint;
 
-import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs;
-
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -23,17 +20,16 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ScheduledExecutorService;
 
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.groupbasedpolicy.dto.EgKey;
 import org.opendaylight.groupbasedpolicy.dto.EpKey;
-import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointListener;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.arp.ArpTasker;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
@@ -48,22 +44,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointFields;
 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.fields.L3AddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressKey;
 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.EndpointKey;
 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.l3endpoint.rev151217.NatAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayConfig;
-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.OfOverlayContext;;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayL3Context;
 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.L2BridgeDomain;
 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.policy.ExternalImplicitGroup;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
@@ -725,10 +714,10 @@ public class EndpointManager implements AutoCloseable {
      * @return the
      *         {@link org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3}
      */
-    public Collection<EndpointL3> getL3EndpointsWithNat() {
+    public @Nonnull Collection<EndpointL3> getL3EndpointsWithNat() {
         Collection<EndpointL3> l3Endpoints = getL3Endpoints();
         if (l3Endpoints == null) {
-            return null;
+            return Collections.emptySet();
         }
         l3Endpoints = Collections2.filter(l3Endpoints, new Predicate<EndpointL3>() {
 
@@ -738,9 +727,6 @@ public class EndpointManager implements AutoCloseable {
                         || (input.getAugmentation(NatAddress.class).getNatAddress() == null));
             }
         });
-        if (l3Endpoints == null) {
-            return Collections.emptySet();
-        }
         return ImmutableSet.copyOf(l3Endpoints);
     }
 
index 9566dfe561e89a4106f7399b8d6c4939481b0433..f501d99a590538124e3d1e08714ac4ba500b3334 100755 (executable)
@@ -8,44 +8,22 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.egressnat;
 
-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.ethernetMatch;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setIpv4SrcAction;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setIpv6SrcAction;
-
-import java.util.Collection;
-
+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.flow.FlowTable;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
-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.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.MatchBuilder;
+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.types.rev131026.instruction.instruction.go.to.table._case.GoToTable;
-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.common.rev140421.L2BridgeDomainId;
 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.EndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-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.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;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
 
 /**
  * <h1>Manage the table that assigns source endpoint group, bridge domain, and
@@ -62,84 +40,51 @@ import org.slf4j.LoggerFactory;
  *      - {@link GoToTable} EXTERNAL MAPPER table<br>
  */
 public class EgressNatMapper extends FlowTable {
-
-    protected static final Logger LOG = LoggerFactory.getLogger(EgressNatMapper.class);
-
-    // TODO Li alagalah Improve UT coverage for this class.
-    public static short TABLE_ID;
+    // Priorities
+    private static final Integer DROP = 1;
+    private static final Integer NAT = 100;
+    private final short tableId;
 
     public EgressNatMapper(OfContext ctx, short tableId) {
         super(ctx);
-        TABLE_ID=tableId;
+        this.tableId = tableId;
     }
 
     @Override
     public short getTableId() {
-        return TABLE_ID;
+        return tableId;
     }
 
     @Override
     public void sync(Endpoint endpoint, OfWriter ofWriter) throws Exception {
-
-        // TODO: only temporary workaround, use src & dst endpoint in implementation
-        NodeId nodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
-
-        ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
-
-        Collection<EndpointL3> l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat();
-        for (EndpointL3 l3Ep : l3Endpoints) {
-            Flow flow = addNatFlow(l3Ep);
-            if (flow==null) {
-                continue;
-            }
-            ofWriter.writeFlow(nodeId, TABLE_ID, flow);
-        }
-    }
-
-    private Flow addNatFlow(EndpointL3 l3Ep) throws Exception {
-        NatAddress natAugL3Endpoint = l3Ep.getAugmentation(NatAddress.class);
-        // Match on L3 Nat Augmentation in Destination, set to IPAddress/Mac, send to SourceMapper
-        if (natAugL3Endpoint != null) {
-            return buildNatFlow(l3Ep.getIpAddress(), natAugL3Endpoint.getNatAddress(), l3Ep.getTenant(),
-                    l3Ep.getL3Context());
+        NodeId endpointNodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
+        if (endpointNodeId == null) {
+            LOG.warn("Endpoint {} has no location specified, skipped", endpoint);
+            return;
         }
-        return null;
+        syncFlows(new EgressNatMapperFlows(endpointNodeId, tableId), endpoint, ofWriter);
     }
 
-    private Flow buildNatFlow(IpAddress insideAddress, IpAddress outsideAddress, TenantId tenantId, L3ContextId l3Ctx) throws Exception {
-        MatchBuilder mb = new MatchBuilder();
-        Action setSrcIp;
-        String insideIpMatch;
-        Layer3Match m;
+    void syncFlows(EgressNatMapperFlows flows, Endpoint endpoint, OfWriter ofWriter) {
 
-        FlowId flowid = new FlowId(new StringBuilder().append("EgressNat")
-            .append("|")
-            .append(insideAddress)
-            .append("|")
-            .append(outsideAddress)
-            .toString());
-        if (outsideAddress.getIpv4Address() != null) {
-            setSrcIp = setIpv4SrcAction(outsideAddress.getIpv4Address());
+        // Drop
+        flows.dropFlow(DROP, null, ofWriter);
 
-            insideIpMatch = insideAddress.getIpv4Address().getValue() + "/32";
-            m = new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(insideIpMatch)).build();
-            mb.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv4)).setLayer3Match(m);
-        } else if (outsideAddress.getIpv6Address() != null) {
-            setSrcIp = setIpv6SrcAction(outsideAddress.getIpv6Address());
-            insideIpMatch = insideAddress.getIpv6Address().getValue() + "/128";
-            m = new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(insideIpMatch)).build();
-            mb.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv6)).setLayer3Match(m);
-        } else {
-            return null;
+        // NAT flows
+        short externalMapperId = ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER();
+        Collection<EndpointL3> l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat();
+        EndpointKey endpointKey = endpoint.getKey();
+        for (EndpointL3 l3Endpoint : l3Endpoints) {
+            L2BridgeDomainId l2Context = l3Endpoint.getL2Context();
+            MacAddress macAddress = l3Endpoint.getMacAddress();
+            if (l2Context != null && macAddress != null) {
+                Endpoint l2EpFromL3Ep = ctx.getEndpointManager().getEndpoint(new EpKey(l2Context, macAddress));
+                if(endpointKey.equals(l2EpFromL3Ep.getKey())) {
+                    flows.natFlows(externalMapperId, l3Endpoint, NAT, ofWriter);
+                    // L3 Endpoint found, end of loop
+                    break;
+                }
+            }
         }
-
-        addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(OrdinalFactory.getContextOrdinal(tenantId, l3Ctx))));
-
-        FlowBuilder flowb = base().setPriority(Integer.valueOf(100))
-            .setId(flowid)
-            .setMatch(mb.build())
-            .setInstructions(
-                    instructions(applyActionIns(setSrcIp), gotoTableIns(ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER())));
-        return flowb.build();
     }
 }
diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlows.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/egressnat/EgressNatMapperFlows.java
new file mode 100644 (file)
index 0000000..33dbfbd
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * 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.egressnat;
+
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
+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.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.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+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.endpoints.EndpointL3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+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.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;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
+
+public class EgressNatMapperFlows {
+
+    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(EgressNatMapperFlows.class);
+    private final NodeId nodeId;
+    private final short tableId;
+
+    public EgressNatMapperFlows(NodeId nodeId, short tableId) {
+        this.nodeId = nodeId;
+        this.tableId = tableId;
+    }
+
+    /**
+     * Default flow which drops 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());
+    }
+
+    /**
+     * For every L3 endpoint with NAT augmentation. Match on inside IP address
+     *
+     * @param goToTable   external mapper table Id
+     * @param l3Endpoint  corresponding {@link EndpointL3}
+     * @param priority    of the flow
+     * @param ofWriter    flow writer
+     */
+    void natFlows(short goToTable, EndpointL3 l3Endpoint, int priority, OfWriter ofWriter) {
+        NatAddress natAugL3Endpoint = l3Endpoint.getAugmentation(NatAddress.class);
+        if (natAugL3Endpoint == null) {
+            return;
+        }
+        // Match on L3 Nat Augmentation in Destination, set to IPAddress/Mac, send to SourceMapper
+        Flow flow = buildNatFlow(goToTable, priority, l3Endpoint.getIpAddress(), natAugL3Endpoint.getNatAddress(),
+                l3Endpoint.getTenant(), l3Endpoint.getL3Context());
+        ofWriter.writeFlow(nodeId, tableId, flow);
+    }
+
+    private Flow buildNatFlow(short goToTable, int priority, IpAddress insideAddress, IpAddress outsideAddress,
+                              TenantId tenantId, L3ContextId l3Ctx) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        Action setSrcIp;
+        String insideIpMatch;
+        Layer3Match layer3Match;
+
+        FlowId flowId = new FlowId(new StringBuilder().append("EgressNat")
+                .append("|")
+                .append(insideAddress)
+                .append("|")
+                .append(outsideAddress)
+                .toString());
+        if (outsideAddress.getIpv4Address() != null) {
+            setSrcIp = setIpv4SrcAction(outsideAddress.getIpv4Address());
+            insideIpMatch = insideAddress.getIpv4Address().getValue() + "/32";
+            layer3Match = new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(insideIpMatch)).build();
+            matchBuilder.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv4)).setLayer3Match(layer3Match);
+        } else if (outsideAddress.getIpv6Address() != null) {
+            setSrcIp = setIpv6SrcAction(outsideAddress.getIpv6Address());
+            insideIpMatch = insideAddress.getIpv6Address().getValue() + "/128";
+            layer3Match = new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(insideIpMatch)).build();
+            matchBuilder.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv6)).setLayer3Match(layer3Match);
+        } else {
+            return null;
+        }
+
+        long contextOrdinal;
+        try {
+            contextOrdinal = OrdinalFactory.getContextOrdinal(tenantId, l3Ctx);
+        } catch (Exception e) {
+            LOG.error("Failed to get L3 context ordinal, L3 context ID: {}", l3Ctx);
+            return null;
+        }
+
+        addNxRegMatch(matchBuilder, RegMatch.of(NxmNxReg6.class, contextOrdinal));
+
+        FlowBuilder flowBuilder = base(tableId).setPriority(priority)
+                .setId(flowId)
+                .setMatch(matchBuilder.build())
+                .setInstructions(
+                        instructions(applyActionIns(setSrcIp), gotoTableIns(goToTable)));
+        return flowBuilder.build();
+    }
+}
index d5a032c24a1c21562dae1ab703f12ae21d6044dd..3792f412bf2314892ba88a0ef300f7885b2187b3 100755 (executable)
@@ -8,66 +8,22 @@
 
 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.ingressnat;
 
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ARP;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
-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.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.renderer.ofoverlay.flow.FlowUtils.setIpv4DstAction;
-import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.setIpv6DstAction;
-
-import java.math.BigInteger;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Set;
-
-import org.apache.commons.lang3.ArrayUtils;
+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.flow.FlowIdUtils;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTable;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.external.ExternalMapper;
-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.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.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.common.rev140421.L2BridgeDomainId;
 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.EndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.Segmentation;
-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.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.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.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;
@@ -75,10 +31,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.NxmNxReg6;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Sets;
+import java.util.Collection;
+import java.util.Collections;
 
 /**
  * <h1>Manage the table processing NAT translation (table=1)</h1>
@@ -144,284 +99,93 @@ import com.google.common.collect.Sets;
  */
 public class IngressNatMapper extends FlowTable {
 
-    protected static final Logger LOG = LoggerFactory.getLogger(IngressNatMapper.class);
-
-    // TODO Li alagalah Improve UT coverage for this class.
-    public static short TABLE_ID;
+    // Priorities
+    private static final Integer BASE = 1;
+    private static final Integer ARP_EXTERNAL = 80;
+    private static final Integer NAT_EXTERNAL = 90;
+    private static final Integer NAT = 100;
+    private static final Integer ARP = 150;
+    private final short tableId;
 
     public IngressNatMapper(OfContext ctx, short tableId) {
         super(ctx);
-        TABLE_ID = tableId;
+        this.tableId = tableId;
     }
 
     @Override
     public short getTableId() {
-        return TABLE_ID;
+        return tableId;
     }
 
     @Override
-    public void sync(Endpoint endpoint, OfWriter ofWriter) throws Exception {
+    public void sync(Endpoint endpoint, OfWriter ofWriter) {
+        NodeId endpointNodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
+        if (endpointNodeId == null) {
+            LOG.warn("Endpoint {} has no location specified, skipped", endpoint);
+            return;
+        }
+        IngressNatMapperFlows flows = new IngressNatMapperFlows(endpointNodeId, tableId);
+        syncFlows(flows, endpoint, ofWriter);
+    }
 
-        // TODO: only temporary workaround, use src & dst endpoint in implementation
-        NodeId nodeId = ctx.getEndpointManager().getEndpointNodeId(endpoint);
+    void syncFlows(IngressNatMapperFlows flows, Endpoint endpoint, OfWriter ofWriter) {
 
-        /*
-         * To support provider networks, all external ingress traffic is currently passed here and
-         * if no match is found - no NAT is performed and processing continues in DestinationMapper.
-         */
-        Flow flow = base()
-                .setTableId(TABLE_ID)
-                .setPriority(1)
-            .setInstructions(
-                    FlowUtils.instructions(FlowUtils.gotoTableIns(
-                        ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())))
-                .setId(FlowIdUtils.newFlowId("gotoDestinationMapper"))
-                .build();
-        ofWriter.writeFlow(nodeId, TABLE_ID, flow);
+        // To support provider networks, all external ingress traffic is currently passed here and
+        // if no match is found - no NAT is performed and processing continues in DestinationMapper.
 
-        // TODO Bug 3546 - Difficult: External port is unrelated to Tenant, L3C, L2BD..
+        // Base flow
+        short destinationMapperId = ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER();
+        flows.baseFlow(destinationMapperId, BASE, ofWriter);
 
         // Flows for ingress NAT translation
-        Collection<Endpoint> endpointsForNode = ctx.getEndpointManager().getEndpointsForNode(nodeId);
         Collection<EndpointL3> l3Endpoints = ctx.getEndpointManager().getL3EndpointsWithNat();
-        for (EndpointL3 l3Ep : l3Endpoints) {
-            if (l3Ep.getL2Context() != null && l3Ep.getMacAddress() !=null ) {
-                Endpoint ep = ctx.getEndpointManager().getEndpoint(new EpKey(l3Ep.getL2Context(), l3Ep.getMacAddress()));
-                if (endpointsForNode.contains(ep)) {
-                    createNatFlow(l3Ep, nodeId, ofWriter);
+        OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals = getEndpointOrdinals(endpoint);
+        EndpointKey endpointKey = endpoint.getKey();
+        for (EndpointL3 l3Endpoint : l3Endpoints) {
+            L2BridgeDomainId l2Context = l3Endpoint.getL2Context();
+            MacAddress macAddress = l3Endpoint.getMacAddress();
+            if (l2Context != null && macAddress != null) {
+                Endpoint l2EpFromL3Ep = ctx.getEndpointManager().getEndpoint(new EpKey(l2Context, macAddress));
+                if(endpointKey.equals(l2EpFromL3Ep.getKey())) {
+                    if (epFwdCtxOrdinals != null) {
+                        flows.createNatFlow(destinationMapperId, l3Endpoint, epFwdCtxOrdinals, NAT, ofWriter);
+                    }
+                    IndexedTenant tenant = ctx.getTenant(endpoint.getTenant());
+                    if (tenant != null) {
+                        flows.createArpFlow(tenant, l3Endpoint, ARP, ofWriter);
+                    }
+                    // L3 Endpoint found, end of loop
+                    break;
                 }
             }
         }
-        //Flows for ingress traffic that does not have to be translated.
-        // TODO similar loop in DestinationMapper
-        for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
-            for (EgKey egKey : ctx.getEndpointManager().getEgKeysForEndpoint(ep)) {
-                Set<EgKey> groups = ctx.getCurrentPolicy().getPeers(egKey);
-                for (EgKey peer : Sets.union(Collections.singleton(egKey), ctx.getCurrentPolicy().getPeers(egKey))) {
-                    for (Endpoint extEp : ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)) {
-                        createIngressExternalFlows(extEp, nodeId, ofWriter);
+        // Flows for ingress traffic that does not have to be translated.
+        for (EgKey endpointGroupKey : ctx.getEndpointManager().getEgKeysForEndpoint(endpoint)) {
+            for (EgKey peer : Sets.union(Collections.singleton(endpointGroupKey),
+                    ctx.getCurrentPolicy().getPeers(endpointGroupKey))) {
+                for (Endpoint externalEndpoint : ctx.getEndpointManager().getExtEpsNoLocForGroup(peer)) {
+                    if (epFwdCtxOrdinals != null) {
+                        flows.createIngressExternalNatFlows(destinationMapperId, externalEndpoint, epFwdCtxOrdinals,
+                                NAT_EXTERNAL, ofWriter);
+                        flows.createIngressExternalArpFlows(destinationMapperId, externalEndpoint, epFwdCtxOrdinals,
+                                ARP_EXTERNAL, ofWriter);
                     }
                 }
             }
         }
     }
 
-    private void createNatFlow(EndpointL3 l3Ep, NodeId nodeId, OfWriter ofWriter) throws Exception {
-        NatAddress natAugL3Endpoint = l3Ep.getAugmentation(NatAddress.class);
-        // Match on L3 Nat Augmentation in Destination, set to IPAddress/Mac, send to SourceMapper
-        if (natAugL3Endpoint == null) {
-            return;
-        }
-        Endpoint ep = ctx.getEndpointManager().getEndpoint(new EpKey(l3Ep.getL2Context(), l3Ep.getMacAddress()));
-        EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, ep);
-        if (epFwdCtxOrds == null) {
-            LOG.info("getEndpointFwdCtxOrdinals is null for EP {}", ep);
-            return;
-        }
-        Flow flow = buildNatFlow(natAugL3Endpoint.getNatAddress(), l3Ep.getIpAddress(), l3Ep.getMacAddress(), epFwdCtxOrds);
-        if (flow != null) {
-            ofWriter.writeFlow(nodeId, TABLE_ID, flow);
-        }
-        flow = createOutsideArpFlow(l3Ep.getTenant(), natAugL3Endpoint.getNatAddress(), l3Ep.getMacAddress(), nodeId);
-        if (flow != null) {
-            ofWriter.writeFlow(nodeId, TABLE_ID, flow);
-        }
-    }
-
-    private void createIngressExternalFlows(Endpoint ep, NodeId nodeId, OfWriter ofWriter) throws Exception {
-        EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, ep);
-        if (epFwdCtxOrds == null) {
-            LOG.info("getEndpointFwdCtxOrdinals is null for EP {}", ep);
-            return;
-        }
-        if (ep.getL3Address() != null) {
-            for (L3Address l3Addr : ep.getL3Address()) {
-                Flow ipFlow = buildIngressExternalIpFlow(l3Addr.getIpAddress(), epFwdCtxOrds);
-                if (ipFlow != null) {
-                    ofWriter.writeFlow(nodeId, TABLE_ID, ipFlow);
-                }
+    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;
             }
-        }
-        Flow arpFlow = buildIngressExternalArpFlow(ep.getMacAddress(), epFwdCtxOrds);
-        if (arpFlow != null) {
-            ofWriter.writeFlow(nodeId, TABLE_ID, arpFlow);
-        }
-    }
-
-    private Flow buildNatFlow(IpAddress outsideDestAddress, IpAddress insideDestAddress, MacAddress toMac,
-            EndpointFwdCtxOrdinals epFwdCtxOrds) {
-        Action setDestIp;
-        Action setDestMac = setDlDstAction(toMac);
-        FlowId flowid = new FlowId(new StringBuilder().append("IngressNat")
-            .append("|")
-            .append(outsideDestAddress)
-            .append("|")
-            .append(insideDestAddress)
-            .append("|")
-            .append(toMac)
-            .toString());
-        if (insideDestAddress.getIpv4Address() != null) {
-            setDestIp = setIpv4DstAction(insideDestAddress.getIpv4Address());
-        } else if (insideDestAddress.getIpv6Address() != null) {
-            setDestIp = setIpv6DstAction(insideDestAddress.getIpv6Address());
-        } else {
-            return null;
-        }
-        MatchBuilder mb = createMatchOnDstIpAddress(outsideDestAddress);
-        Action[] dstIpMacAction = {setDestIp, setDestMac};
-        FlowBuilder flowb = base().setPriority(100)
-            .setId(flowid)
-            .setMatch(mb.build())
-            .setInstructions(
-                    instructions(
-                            applyActionIns(ArrayUtils.addAll(dstIpMacAction, createEpFwdCtxActions(epFwdCtxOrds))),
-                            gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
-        return flowb.build();
-    }
-
-    private Flow createOutsideArpFlow(TenantId tenantId, IpAddress outsideDestAddress, MacAddress toMac, NodeId nodeId) {
-        String ikey = outsideDestAddress.getIpv4Address().getValue();
-        BigInteger intMac = new BigInteger(1, bytesFromHexString(toMac.getValue()));
-        MatchBuilder mb = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP)).setLayer3Match(
-                new ArpMatchBuilder().setArpOp(1)
-                    .setArpTargetTransportAddress(new Ipv4Prefix(ikey + "/32"))
-                    .build());
-        Action[] outsideArpActions = {
-                nxMoveEthSrcToEthDstAction(),
-                setDlSrcAction(toMac),
-                nxLoadArpOpAction(BigInteger.valueOf(2L)),
-                nxMoveArpShaToArpThaAction(),
-                nxLoadArpShaAction(intMac),
-                nxMoveArpSpaToArpTpaAction(),
-                nxLoadArpSpaAction(ikey),
-                outputAction(new NodeConnectorId(nodeId.getValue() + ":INPORT"))
-        };
-        Subnet extSubnet = ExternalMapper.resolveSubnetForIpv4Address(ctx.getTenant(tenantId),
-                outsideDestAddress.getIpv4Address());
-        L2FloodDomain l2Fd = null;
-        if (extSubnet != null && extSubnet.getParent() != null) {
-            l2Fd = ctx.getTenant(tenantId).resolveL2FloodDomain(extSubnet.getParent());
-        }
-        FlowBuilder flowb = base().setPriority(150);
-        if (l2Fd != null && l2Fd.getAugmentation(Segmentation.class) != null) {
-            Integer vlanId = l2Fd.getAugmentation(Segmentation.class).getSegmentationId();
-            mb.setVlanMatch(FlowUtils.vlanMatch(0, false));
-            Action[] pushVlanpActions = {FlowUtils.pushVlanAction(), FlowUtils.setVlanId(vlanId)};
-            flowb.setInstructions(instructions(FlowUtils.applyActionIns(ArrayUtils.addAll(
-                    pushVlanpActions,
-                    outsideArpActions))));
-        } else {
-            flowb.setInstructions(instructions(FlowUtils.applyActionIns(outsideArpActions)));
-        }
-        flowb.setId(FlowIdUtils.newFlowId(TABLE_ID, "outside-ip-arp", mb.build()));
-        flowb.setMatch(mb.build());
-        return flowb.build();
-    }
-
-    /**
-     * Builds flow for inbound IP traffic of registered external endpoint.
-     * Priority should be lower than in NAT flow.
-     */
-    private Flow buildIngressExternalIpFlow(IpAddress srcIpAddress, EndpointFwdCtxOrdinals epFwdCtxOrds) {
-        MatchBuilder mb = createMatchOnSrcIpAddress(srcIpAddress);
-        if (mb == null) {
-            return null;
-        }
-        FlowBuilder flowb = base().setPriority(90)
-            .setId(FlowIdUtils.newFlowId(TABLE_ID, "inbound-external-ip", mb.build()))
-            .setMatch(mb.build())
-            .setInstructions(
-                    instructions(applyActionIns(createEpFwdCtxActions(epFwdCtxOrds)),
-                            gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
-        return flowb.build();
-    }
-
-    /**
-     * @param srcIpAddress can be IPv4 or IPv6
-     * @return {@link MatchBuilder} with specified L2 ethertype and L3 source address.
-     *  Returns null if srcIpAddress is null.
-     */
-    private MatchBuilder createMatchOnSrcIpAddress(IpAddress srcIpAddress) {
-        return createMatchOnIpAddress(srcIpAddress, true);
-    }
-
-    private MatchBuilder createMatchOnDstIpAddress(IpAddress srcIpAddress) {
-        return createMatchOnIpAddress(srcIpAddress, false);
-    }
-
-    // use createMatchOnSrcIpAddress or createMatchOnDstIpAddress
-    private MatchBuilder createMatchOnIpAddress(IpAddress srcIpAddress, boolean isSourceAddress) {
-        MatchBuilder mb = new MatchBuilder();
-        String ipPrefix;
-        Layer3Match m;
-        if (srcIpAddress.getIpv4Address() != null) {
-            ipPrefix = srcIpAddress.getIpv4Address().getValue() + "/32";
-            m = (isSourceAddress) ? new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(ipPrefix)).build() :
-                new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ipPrefix)).build();
-            mb.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv4))
-              .setLayer3Match(m);
-            return mb;
-        } else if (srcIpAddress.getIpv6Address() != null) {
-            ipPrefix = srcIpAddress.getIpv6Address().getValue() + "/128";
-            m = (isSourceAddress) ? new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(ipPrefix)).build() :
-                new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ipPrefix)).build();
-            mb.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv6))
-              .setLayer3Match(m);
-            return mb;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Builds flow for inbound ARP traffic of registered external endpoint.
-     * Priority should be lower than in ARP flow for NAT address.
-     */
-    private Flow buildIngressExternalArpFlow(MacAddress srcMac, EndpointFwdCtxOrdinals epFwdCtxOrds) {
-        if (srcMac == null) {
+            return ordinals;
+        } catch (Exception e) {
+            LOG.error("Failed to get endpoint ordinals, endpoint: {}", endpoint);
             return null;
         }
-        MatchBuilder mb = new MatchBuilder()
-            .setEthernetMatch(ethernetMatch(srcMac, null, ARP));
-            //.setLayer3Match(
-            //        new ArpMatchBuilder()
-           //             .setArpOp(Integer.valueOf(2))
-           //             .build());
-        FlowBuilder flowb = base().setPriority(80);
-        flowb.setInstructions(instructions(applyActionIns(createEpFwdCtxActions(epFwdCtxOrds)),
-                gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
-        flowb.setId(FlowIdUtils.newFlowId(TABLE_ID, "inbound-external-arp", mb.build()));
-        flowb.setMatch(mb.build());
-        return flowb.build();
-    }
-
-    private Action[] createEpFwdCtxActions(EndpointFwdCtxOrdinals epFwdCtxOrds) {
-        int egId = epFwdCtxOrds.getEpgId();
-        int bdId = epFwdCtxOrds.getBdId();
-        int fdId = epFwdCtxOrds.getFdId();
-        int l3Id = epFwdCtxOrds.getL3Id();
-        int cgId = epFwdCtxOrds.getCgId();
-        int tunnelId = epFwdCtxOrds.getTunnelId();
-        Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId));
-        Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(cgId));
-        Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId));
-        Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
-        Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id));
-        Action tunIdAction = nxLoadTunIdAction(BigInteger.valueOf(tunnelId), false);
-        return new Action[]{segReg, scgReg, bdReg, fdReg, vrfReg, tunIdAction};
-    }
-
-    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/mapper/ingressnat/IngressNatMapperFlows.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/mapper/ingressnat/IngressNatMapperFlows.java
new file mode 100644 (file)
index 0000000..4cf70f9
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * 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.ingressnat;
+
+import com.google.common.base.Preconditions;
+import org.apache.commons.lang3.ArrayUtils;
+import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
+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.external.ExternalMapper;
+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.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.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.EndpointL3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.l3endpoint.rev151217.NatAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.Segmentation;
+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.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.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.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;
+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.math.BigInteger;
+
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
+
+/**
+ * Building and writing of specific flows according to data from {@link IngressNatMapper}
+ */
+class IngressNatMapperFlows {
+
+    private final NodeId nodeId;
+    private final short tableId;
+
+    IngressNatMapperFlows(NodeId nodeId, short tableId) {
+        this.nodeId = Preconditions.checkNotNull(nodeId);
+        this.tableId = Preconditions.checkNotNull(tableId);
+    }
+
+    /**
+     * Ingress NAT mapper base flow does not drop packets, instead of that it pass all traffic which does not match
+     * to destination mapper
+     *
+     * @param goToTable table ID for {@link GoToTable} instruction
+     * @param priority  of the base flow
+     * @param ofWriter  flow writer
+     */
+    void baseFlow(short goToTable, int priority, OfWriter ofWriter) {
+        Flow flow = FlowUtils.base(tableId)
+                .setTableId(tableId)
+                .setPriority(priority)
+                .setInstructions(FlowUtils.instructions(FlowUtils.gotoTableIns(goToTable)))
+                .setId(FlowIdUtils.newFlowId("gotoDestinationMapper"))
+                .build();
+        ofWriter.writeFlow(nodeId, tableId, flow);
+    }
+
+    /**
+     * Ingress NAT translation flow, matches on L3 NAT address
+     *
+     * @param goToTable              table ID for {@link GoToTable} instruction
+     * @param l3Ep                   endpoint which should contain L3 NAT augmentation
+     * @param endpointFwdCtxOrdinals resolved endpoint ordinals
+     * @param priority               of the flow
+     * @param ofWriter               flow writer
+     */
+    void createNatFlow(short goToTable, EndpointL3 l3Ep, OrdinalFactory.EndpointFwdCtxOrdinals endpointFwdCtxOrdinals,
+                       int priority, OfWriter ofWriter) {
+
+        // Match on L3 Nat Augmentation in Destination, set to IPAddress/Mac, send to SourceMapper
+        NatAddress natAugL3Endpoint = l3Ep.getAugmentation(NatAddress.class);
+        if (natAugL3Endpoint == null || natAugL3Endpoint.getNatAddress() == null) {
+            return;
+        }
+
+        // NAT flow
+        if (l3Ep.getMacAddress() != null || l3Ep.getIpAddress() != null) {
+            Flow flow = buildNatFlow(goToTable, natAugL3Endpoint.getNatAddress(), priority, l3Ep.getIpAddress(),
+                    l3Ep.getMacAddress(), endpointFwdCtxOrdinals);
+            if (flow != null) {
+                ofWriter.writeFlow(nodeId, tableId, flow);
+            }
+        }
+    }
+
+    /**
+     * Ingress NAT outside arp flow
+     *
+     * @param tenant   {@link IndexedTenant} object
+     * @param l3Ep     endpoint which should contain L3 NAT augmentation
+     * @param priority of the flow
+     * @param ofWriter flow writer
+     */
+    void createArpFlow(IndexedTenant tenant, EndpointL3 l3Ep, int priority, OfWriter ofWriter) {
+        NatAddress natAugL3Endpoint = l3Ep.getAugmentation(NatAddress.class);
+        if (natAugL3Endpoint == null || natAugL3Endpoint.getNatAddress() == null) {
+            return;
+        }
+
+        // ARP flow
+        if (l3Ep.getIpAddress() != null) {
+            Flow flow = createOutsideArpFlow(tenant, priority, natAugL3Endpoint.getNatAddress(),
+                    l3Ep.getMacAddress(), nodeId);
+            if (flow != null) {
+                ofWriter.writeFlow(nodeId, tableId, flow);
+            }
+        }
+    }
+
+    /**
+     * NAT flow for for inbound IP traffic of registered external endpoint. NAT augmentation is not used here.
+     *
+     * @param goToTable              table ID for {@link GoToTable} instruction
+     * @param endpoint               should contain ordinals and ip address
+     * @param endpointFwdCtxOrdinals resolved endpoint ordinals
+     * @param priority               of the flow
+     * @param ofWriter               flow writer
+     */
+    void createIngressExternalNatFlows(short goToTable, Endpoint endpoint, OrdinalFactory.EndpointFwdCtxOrdinals
+            endpointFwdCtxOrdinals, int priority, OfWriter ofWriter) {
+        if (endpoint.getL3Address() != null) {
+            for (L3Address l3Address : endpoint.getL3Address()) {
+                // Priority should be lower than in NAT flow
+                Flow ipFlow = buildIngressExternalIpFlow(goToTable, l3Address.getIpAddress(), priority,
+                        endpointFwdCtxOrdinals);
+                if (ipFlow != null) {
+                    ofWriter.writeFlow(nodeId, tableId, ipFlow);
+                }
+            }
+        }
+    }
+
+    /**
+     * ARP flow for for inbound IP traffic of registered external endpoint. NAT augmentation is not used here.
+     *
+     * @param goToTable              table ID for {@link GoToTable} instruction
+     * @param endpoint               should contain ordinals and ip address
+     * @param endpointFwdCtxOrdinals resolved endpoint ordinals
+     * @param priority               of the flow
+     * @param ofWriter               flow writer
+     */
+    void createIngressExternalArpFlows(short goToTable, Endpoint endpoint, OrdinalFactory.EndpointFwdCtxOrdinals
+            endpointFwdCtxOrdinals, int priority, OfWriter ofWriter) {
+        if (endpoint.getMacAddress() != null) {
+            // Priority should be lower than in ARP flow for NAT address
+            Flow arpFlow = buildIngressExternalArpFlow(goToTable, endpoint.getMacAddress(), priority,
+                    endpointFwdCtxOrdinals);
+            if (arpFlow != null) {
+                ofWriter.writeFlow(nodeId, tableId, arpFlow);
+            }
+        }
+    }
+
+    private Flow buildNatFlow(short goToTable, IpAddress outsideDstAddress, int priority, IpAddress insideDstAddress,
+                              MacAddress toMac, OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals) {
+        Action setDstIp;
+        Action setDstMac = setDlDstAction(toMac);
+        FlowId flowid = new FlowId(new StringBuilder().append("IngressNat")
+                .append("|")
+                .append(outsideDstAddress)
+                .append("|")
+                .append(insideDstAddress)
+                .append("|")
+                .append(toMac)
+                .toString());
+        if (insideDstAddress.getIpv4Address() != null) {
+            setDstIp = setIpv4DstAction(insideDstAddress.getIpv4Address());
+        } else if (insideDstAddress.getIpv6Address() != null) {
+            setDstIp = setIpv6DstAction(insideDstAddress.getIpv6Address());
+        } else {
+            return null;
+        }
+        MatchBuilder matchBuilder = createMatchOnIpAddress(outsideDstAddress, false);
+        if (matchBuilder == null) {
+            return null;
+        }
+        Action[] dstIpMacAction = {setDstIp, setDstMac};
+        FlowBuilder flowBuilder = base(tableId).setPriority(priority)
+                .setId(flowid)
+                .setMatch(matchBuilder.build())
+                .setInstructions(instructions(
+                        applyActionIns(ArrayUtils.addAll(dstIpMacAction, createEpFwdCtxActions(epFwdCtxOrdinals))),
+                        gotoTableIns(goToTable)));
+        return flowBuilder.build();
+    }
+
+    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()));
+        MatchBuilder matchBuilder = new MatchBuilder().setEthernetMatch(ethernetMatch(null, null, ARP)).setLayer3Match(
+                new ArpMatchBuilder().setArpOp(1)
+                        .setArpTargetTransportAddress(new Ipv4Prefix(ikey + "/32"))
+                        .build());
+        Action[] outsideArpActions = {
+                nxMoveEthSrcToEthDstAction(),
+                setDlSrcAction(toMac),
+                nxLoadArpOpAction(BigInteger.valueOf(2L)),
+                nxMoveArpShaToArpThaAction(),
+                nxLoadArpShaAction(intMac),
+                nxMoveArpSpaToArpTpaAction(),
+                nxLoadArpSpaAction(ikey),
+                outputAction(new NodeConnectorId(nodeId.getValue() + ":INPORT"))
+        };
+        Subnet extSubnet = ExternalMapper.resolveSubnetForIpv4Address(tenant, outsideDestAddress.getIpv4Address());
+        L2FloodDomain l2Fd = null;
+        if (extSubnet != null && extSubnet.getParent() != null) {
+            l2Fd = tenant.resolveL2FloodDomain(extSubnet.getParent());
+        }
+        FlowBuilder flowBuilder = base(tableId).setPriority(priority);
+        if (l2Fd != null && l2Fd.getAugmentation(Segmentation.class) != null) {
+            Integer vlanId = l2Fd.getAugmentation(Segmentation.class).getSegmentationId();
+            matchBuilder.setVlanMatch(FlowUtils.vlanMatch(0, false));
+            Action[] pushVlanActions = {FlowUtils.pushVlanAction(), FlowUtils.setVlanId(vlanId)};
+            flowBuilder.setInstructions(instructions(FlowUtils.applyActionIns(ArrayUtils.addAll(
+                    pushVlanActions,
+                    outsideArpActions))));
+        } else {
+            flowBuilder.setInstructions(instructions(FlowUtils.applyActionIns(outsideArpActions)));
+        }
+        flowBuilder.setId(FlowIdUtils.newFlowId(tableId, "outside-ip-arp", matchBuilder.build()));
+        flowBuilder.setMatch(matchBuilder.build());
+        return flowBuilder.build();
+    }
+
+    private Flow buildIngressExternalIpFlow(short goToTable, IpAddress srcIpAddress, int priority,
+                                            OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals) {
+        MatchBuilder mb = createMatchOnIpAddress(srcIpAddress, true);
+
+        if (mb == null) {
+            return null;
+        }
+        FlowBuilder flowBuilder = base(tableId).setPriority(priority)
+                .setId(FlowIdUtils.newFlowId(tableId, "inbound-external-ip", mb.build()))
+                .setMatch(mb.build())
+                .setInstructions(
+                        instructions(applyActionIns(createEpFwdCtxActions(epFwdCtxOrdinals)),
+                                gotoTableIns(goToTable)));
+        return flowBuilder.build();
+    }
+
+    private Flow buildIngressExternalArpFlow(short goToTable, MacAddress srcMacAddress, int priority,
+                                             OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals) {
+        if (srcMacAddress == null) {
+            return null;
+        }
+        MatchBuilder mb = new MatchBuilder()
+                .setEthernetMatch(ethernetMatch(srcMacAddress, null, ARP));
+        FlowBuilder flowBuilder = base(tableId).setPriority(priority);
+        flowBuilder.setInstructions(instructions(applyActionIns(createEpFwdCtxActions(epFwdCtxOrdinals)),
+                gotoTableIns(goToTable)));
+        flowBuilder.setId(FlowIdUtils.newFlowId(tableId, "inbound-external-arp", mb.build()));
+        flowBuilder.setMatch(mb.build());
+        return flowBuilder.build();
+    }
+
+    private Action[] createEpFwdCtxActions(OrdinalFactory.EndpointFwdCtxOrdinals epFwdCtxOrdinals) {
+        int egId = epFwdCtxOrdinals.getEpgId();
+        int bdId = epFwdCtxOrdinals.getBdId();
+        int fdId = epFwdCtxOrdinals.getFdId();
+        int l3Id = epFwdCtxOrdinals.getL3Id();
+        int cgId = epFwdCtxOrdinals.getCgId();
+        int tunnelId = epFwdCtxOrdinals.getTunnelId();
+        Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId));
+        Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(cgId));
+        Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId));
+        Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
+        Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id));
+        Action tunIdAction = nxLoadTunIdAction(BigInteger.valueOf(tunnelId), false);
+        return new Action[]{segReg, scgReg, bdReg, fdReg, vrfReg, tunIdAction};
+    }
+
+    private MatchBuilder createMatchOnIpAddress(IpAddress srcIpAddress, boolean isSourceAddress) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String ipPrefix;
+        Layer3Match layer3Match;
+        if (srcIpAddress.getIpv4Address() != null) {
+            ipPrefix = srcIpAddress.getIpv4Address().getValue() + "/32";
+            layer3Match = (isSourceAddress) ? new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(ipPrefix)).build() :
+                    new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(ipPrefix)).build();
+            matchBuilder.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv4))
+                    .setLayer3Match(layer3Match);
+            return matchBuilder;
+        } else if (srcIpAddress.getIpv6Address() != null) {
+            ipPrefix = srcIpAddress.getIpv6Address().getValue() + "/128";
+            layer3Match = (isSourceAddress) ? new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(ipPrefix)).build() :
+                    new Ipv6MatchBuilder().setIpv6Destination(new Ipv6Prefix(ipPrefix)).build();
+            matchBuilder.setEthernetMatch(ethernetMatch(null, null, FlowUtils.IPv6))
+                    .setLayer3Match(layer3Match);
+            return matchBuilder;
+        } else {
+            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;
+    }
+}
index 291f9e9f542183690e9f6f05fab394082962296d..8c79b5207ee0e6f91dada33538ed7178603e0d89 100644 (file)
@@ -49,10 +49,8 @@ class PortSecurityFlows {
     private final Short tableId;
 
     PortSecurityFlows(NodeId nodeId, Short tableId) {
-        Preconditions.checkNotNull(nodeId);
-        Preconditions.checkNotNull(tableId);
-        this.nodeId = nodeId;
-        this.tableId = tableId;
+        this.nodeId = Preconditions.checkNotNull(nodeId);
+        this.tableId = Preconditions.checkNotNull(tableId);
     }
 
     /**
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/EgressNatMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/EgressNatMapperTest.java
deleted file mode 100755 (executable)
index a24ced5..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2015 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.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 java.util.Arrays;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.groupbasedpolicy.dto.EpKey;
-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.mapper.egressnat.EgressNatMapper;
-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.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.L2BridgeDomainId;
-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.l3endpoint.rev151217.NatAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-
-public class EgressNatMapperTest {
-
-    private EgressNatMapper mapper;
-
-    private NodeId nodeId;
-    private OfWriter ofWriter;
-
-    private IpAddress ipAddressNapt;
-    private IpAddress ipAddressL3Ep;
-
-    private static final short TABLE_ID = (short) 5;
-    private static final String IPV4_ADDRESS = "127.0.0.1";
-    private static final String MAC_ADDRESS = "FF:FF:FF:FF:FF:FF";
-    private static final String IPV6_ADDRESS = "0:0:0:0:0:0:0:1";
-
-    @Before
-    public void initialisation() {
-        OfContext ctx = mock(OfContext.class);
-
-        EndpointManager endpointManager = mock(EndpointManager.class);
-        when(ctx.getEndpointManager()).thenReturn(endpointManager);
-
-        // endpointL3
-        EndpointL3 endpointL3 = mock(EndpointL3.class);
-        when(endpointManager.getL3EndpointsWithNat()).thenReturn(Arrays.asList(endpointL3));
-        ipAddressL3Ep = mock(IpAddress.class);
-        when(endpointL3.getIpAddress()).thenReturn(ipAddressL3Ep);
-        Ipv4Address ipv4AddressL3Ep = mock(Ipv4Address.class);
-        when(ipAddressL3Ep.getIpv4Address()).thenReturn(ipv4AddressL3Ep);
-        when(ipv4AddressL3Ep.getValue()).thenReturn(IPV4_ADDRESS);
-        L2BridgeDomainId l2BridgeDomainId = mock(L2BridgeDomainId.class);
-        when(endpointL3.getL2Context()).thenReturn(l2BridgeDomainId);
-        MacAddress macAddress = mock(MacAddress.class);
-        when(endpointL3.getMacAddress()).thenReturn(macAddress);
-        when(macAddress.getValue()).thenReturn(MAC_ADDRESS);
-        Ipv6Address ipv6AddressL3Ep = mock(Ipv6Address.class);
-        when(ipAddressL3Ep.getIpv6Address()).thenReturn(ipv6AddressL3Ep);
-        when(ipv6AddressL3Ep.getValue()).thenReturn(IPV6_ADDRESS);
-
-        Endpoint endpoint = mock(Endpoint.class);
-        when(endpointManager.getEndpoint(any(EpKey.class))).thenReturn(endpoint);
-        when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(Arrays.asList(endpoint));
-
-        // createNatFlow
-        ipAddressNapt = mock(IpAddress.class);
-        NatAddress nat = mock(NatAddress.class);
-        when(nat.getNatAddress()).thenReturn(ipAddressNapt);
-        when(endpointL3.getAugmentation(NatAddress.class)).thenReturn(nat);
-        Ipv4Address ipv4AddressNapt = mock(Ipv4Address.class);
-        when(ipAddressNapt.getIpv4Address()).thenReturn(ipv4AddressNapt);
-        when(ipv4AddressNapt.getValue()).thenReturn(IPV4_ADDRESS);
-        Ipv6Address ipv6AddressNapt = mock(Ipv6Address.class);
-        when(ipAddressNapt.getIpv6Address()).thenReturn(ipv6AddressNapt);
-        when(ipv6AddressNapt.getValue()).thenReturn(IPV6_ADDRESS);
-
-        // buildNatFlow
-        PolicyManager policyManager = mock(PolicyManager.class);
-        when(ctx.getPolicyManager()).thenReturn(policyManager);
-        when(policyManager.getTABLEID_DESTINATION_MAPPER()).thenReturn(TABLE_ID);
-
-        nodeId = mock(NodeId.class);
-        ofWriter = mock(OfWriter.class);
-
-        mapper = new EgressNatMapper(ctx, TABLE_ID);
-    }
-
-    @Test
-    public void getTableIdTest() {
-        Assert.assertEquals(TABLE_ID, mapper.getTableId());
-    }
-
-    @Ignore
-    @Test
-    public void syncTestIpv4() throws Exception {
-        //mapper.sync(nodeId, ofWriter);
-        verify(ofWriter, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
-    }
-
-    @Ignore
-    @Test
-    public void syncTestIpv6() throws Exception {
-        when(ipAddressNapt.getIpv4Address()).thenReturn(null);
-        //mapper.sync(nodeId, ofWriter);
-        verify(ofWriter, times(2)).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
-    }
-
-}
diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/IngressNatMapperTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/IngressNatMapperTest.java
deleted file mode 100755 (executable)
index acf43ec..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2015 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.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.groupbasedpolicy.dto.EpKey;
-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.mapper.ingressnat.IngressNatMapper;
-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.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.L2BridgeDomainId;
-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.l3endpoint.rev151217.NatAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-
-public class IngressNatMapperTest {
-
-    private IngressNatMapper mapper;
-
-    private NodeId nodeId;
-    private OfWriter ofWriter;
-
-    private IpAddress ipAddressNapt;
-    private IpAddress ipAddressL3Ep;
-
-    private static final short TABLE_ID = (short) 5;
-    private static final String IPV4_ADDRESS = "127.0.0.1";
-    private static final String MAC_ADDRESS = "FF:FF:FF:FF:FF:FF";
-    private static final String IPV6_ADDRESS = "0:0:0:0:0:0:0:1";
-
-    @Before
-    public void initialisation() {
-        OfContext ctx = mock(OfContext.class);
-
-        EndpointManager endpointManager = mock(EndpointManager.class);
-        when(ctx.getEndpointManager()).thenReturn(endpointManager);
-
-        // endpointL3
-        EndpointL3 endpointL3 = mock(EndpointL3.class);
-        when(endpointManager.getL3EndpointsWithNat()).thenReturn(Arrays.asList(endpointL3));
-        ipAddressL3Ep = mock(IpAddress.class);
-        when(endpointL3.getIpAddress()).thenReturn(ipAddressL3Ep);
-        Ipv4Address ipv4AddressL3Ep = mock(Ipv4Address.class);
-        when(ipAddressL3Ep.getIpv4Address()).thenReturn(ipv4AddressL3Ep);
-        when(ipv4AddressL3Ep.getValue()).thenReturn(IPV4_ADDRESS);
-        L2BridgeDomainId l2BridgeDomainId = mock(L2BridgeDomainId.class);
-        when(endpointL3.getL2Context()).thenReturn(l2BridgeDomainId);
-        MacAddress macAddress = mock(MacAddress.class);
-        when(endpointL3.getMacAddress()).thenReturn(macAddress);
-        when(macAddress.getValue()).thenReturn(MAC_ADDRESS);
-        Ipv6Address ipv6AddressL3Ep = mock(Ipv6Address.class);
-        when(ipAddressL3Ep.getIpv6Address()).thenReturn(ipv6AddressL3Ep);
-        when(ipv6AddressL3Ep.getValue()).thenReturn(IPV6_ADDRESS);
-
-        Endpoint endpoint = mock(Endpoint.class);
-        when(endpointManager.getEndpoint(any(EpKey.class))).thenReturn(endpoint);
-        when(endpointManager.getEndpointsForNode(any(NodeId.class))).thenReturn(Arrays.asList(endpoint));
-
-        // createNatFlow
-        ipAddressNapt = mock(IpAddress.class);
-        NatAddress nat = mock(NatAddress.class);
-        when(nat.getNatAddress()).thenReturn(ipAddressNapt);
-        Ipv4Address ipv4AddressNapt = mock(Ipv4Address.class);
-        when(ipAddressNapt.getIpv4Address()).thenReturn(ipv4AddressNapt);
-        when(ipv4AddressNapt.getValue()).thenReturn(IPV4_ADDRESS);
-        Ipv6Address ipv6AddressNapt = mock(Ipv6Address.class);
-        when(ipAddressNapt.getIpv6Address()).thenReturn(ipv6AddressNapt);
-        when(ipv6AddressNapt.getValue()).thenReturn(IPV6_ADDRESS);
-
-        // buildNatFlow
-        PolicyManager policyManager = mock(PolicyManager.class);
-        when(ctx.getPolicyManager()).thenReturn(policyManager);
-        when(policyManager.getTABLEID_DESTINATION_MAPPER()).thenReturn(TABLE_ID);
-
-        nodeId = mock(NodeId.class);
-        ofWriter = mock(OfWriter.class);
-
-        mapper = new IngressNatMapper(ctx, TABLE_ID);
-    }
-
-    @Test
-    public void getTableIdTest() {
-        Assert.assertEquals(TABLE_ID, mapper.getTableId());
-    }
-
-    @Ignore
-    @Test
-    public void syncTestIpv4() throws Exception {
-        //mapper.sync(nodeId, ofWriter);
-        verify(ofWriter).writeFlow(any(NodeId.class), any(Short.class), any(Flow.class));
-    }
-
-    @Ignore
-    @Test
-    public void syncTestIpv6() throws Exception {
-        when(ipAddressL3Ep.getIpv4Address()).thenReturn(null);
-        //mapper.sync(nodeId, ofWriter);
-        verify(ofWriter).writeFlow(any(NodeId.class), any(Short.class), any(Flow.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
new file mode 100644 (file)
index 0000000..64a8a61
--- /dev/null
@@ -0,0 +1,179 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper;
+
+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.FlowUtils;
+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.inet.types.rev100924.Ipv6Address;
+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;
+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.Instructions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
+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.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.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.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.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.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+
+import java.util.ArrayList;
+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 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 String L2 = "L2";
+    private static final String DOMAIN_ID = "dummy id";
+    protected final NodeId nodeId = new NodeId(NODE_ID);
+    protected Short tableId;
+    protected OfContext ctx;
+    protected OfWriter ofWriter;
+    protected SwitchManager switchManager;
+    protected PolicyManager policyManager;
+    protected EndpointManager endpointManager;
+    protected PolicyInfo policyInfo;
+
+    protected Flow flowCreator(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.build();
+    }
+
+    protected Endpoint endpointCreator(IpAddress ip, MacAddress mac, NodeConnectorId nodeConnectorId) {
+        EndpointBuilder endpointBuilder = new EndpointBuilder();
+
+        // Set tenant
+        endpointBuilder.setTenant(new TenantId(TENANT_ID));
+
+        // Set L3 address
+        if (ip != null) {
+            List<L3Address> l3Addresses = new ArrayList<>();
+            L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
+            l3AddressBuilder.setIpAddress(ip);
+            l3Addresses.add(l3AddressBuilder.build());
+            endpointBuilder.setL3Address(l3Addresses);
+        }
+
+        // Set Mac address
+        endpointBuilder.setMacAddress(new MacAddress(mac));
+
+        // Augment node connector
+        OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
+        ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(nodeConnectorId));
+        endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
+
+        // Set network containment
+        endpointBuilder.setNetworkContainment(new NetworkDomainId(DOMAIN_ID));
+
+        return endpointBuilder.build();
+    }
+
+    protected EndpointL3 endpointL3Creator(String ip, String insideIp, String mac, String l2, boolean ipv6) {
+        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)));
+            }
+        }
+
+        // Set MAC
+        if (mac != null) {
+            endpointL3Builder.setMacAddress(new MacAddress(mac));
+        }
+
+        // Set L2 context
+        if (l2 != null) {
+            endpointL3Builder.setL2Context(new L2BridgeDomainId(l2));
+        }
+
+        return endpointL3Builder.build();
+
+    }
+
+    protected IndexedTenant tenantCreator() {
+        TenantBuilder tenantBuilder = new TenantBuilder();
+        tenantBuilder.setId(new TenantId(TENANT_ID));
+
+        // Set forwarding context
+        SegmentationBuilder segmentationBuilder = new SegmentationBuilder();
+        segmentationBuilder.setSegmentationId(1);
+        List<L2FloodDomain> l2FloodDomains = new ArrayList<>();
+        L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder();
+        l2FloodDomainBuilder.setId(new L2FloodDomainId("l2id"));
+        l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build());
+        l2FloodDomains.add(l2FloodDomainBuilder.build());
+        ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder();
+        forwardingContextBuilder.setL2FloodDomain(l2FloodDomains);
+        tenantBuilder.setForwardingContext(forwardingContextBuilder.build());
+
+        return new IndexedTenant(tenantBuilder.build());
+    }
+
+    protected List<L2FloodDomain> l2FloodDomainsCreator() {
+        SegmentationBuilder segmentationBuilder = new SegmentationBuilder();
+        segmentationBuilder.setSegmentationId(1);
+        List<L2FloodDomain> l2FloodDomains = new ArrayList<>();
+        L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder();
+        l2FloodDomainBuilder.setId(new L2FloodDomainId("l2id"));
+        l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build());
+        l2FloodDomains.add(l2FloodDomainBuilder.build());
+        return l2FloodDomains;
+    }
+}
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
new file mode 100644 (file)
index 0000000..0d64f3c
--- /dev/null
@@ -0,0 +1,152 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.egressnat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
+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.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.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.endpoint.rev140421.endpoints.EndpointL3;
+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.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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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;
+
+    @Before
+    public void init() {
+        tableId = 5;
+        ofWriter = mock(OfWriter.class);
+        flows = new EgressNatMapperFlows(nodeId, tableId);
+    }
+
+    @Test
+    public void testDropFlow_noEthertype() {
+        Flow testFlow = flowCreator(new FlowId(DROP_ALL), tableId, 100, null,
+                FlowUtils.dropInstructions());
+
+        flows.dropFlow(100, null, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, 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 = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
+                FlowUtils.dropInstructions());
+
+        flows.dropFlow(100, FlowUtils.IPv4, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, 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 = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
+                FlowUtils.dropInstructions());
+
+        flows.dropFlow(100, FlowUtils.IPv6, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, 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 = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
+                FlowUtils.dropInstructions());
+
+        flows.dropFlow(100, FlowUtils.ARP, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
+    }
+
+    @Test
+    public void testNatFlows_noAugmentation() {
+        EndpointL3 endpointL3 = endpointL3Creator(null, IPV4_1, MAC_0, L2, false);
+        flows.natFlows((short) 6, endpointL3, 100, ofWriter);
+        verifyZeroInteractions(ofWriter);
+    }
+
+    @Test
+    public void testNatFlows_ipv4() {
+        EndpointL3 endpointL3 = endpointL3Creator(IPV4_1, IPV4_2, MAC_0, L2, false);
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4))
+                .setLayer3Match(new Ipv4MatchBuilder().setIpv4Source(new Ipv4Prefix(IPV4_2 + 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))));
+        InstructionBuilder goTo = new InstructionBuilder();
+        goTo.setOrder(1).setInstruction(FlowUtils.gotoTableIns((short) 6));
+        List<Instruction> instructions = new ArrayList<>();
+        instructions.add(apply.build());
+        instructions.add(goTo.build());
+        instructionsBuilder.setInstruction(instructions);
+
+        Flow testFlow = flowCreator(new FlowId(EGRESS_NAT + new IpAddress(new Ipv4Address(IPV4_2)) + "|" +
+                new IpAddress(new Ipv4Address(IPV4_1))), tableId, 90, match, instructionsBuilder.build());
+
+        flows.natFlows((short) 6, endpointL3, 90, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
+    }
+
+    @Test
+    public void testNatFlows_ipv6() {
+        EndpointL3 endpointL3 = endpointL3Creator(IPV6_1, IPV6_2, MAC_0, L2, true);
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6))
+                .setLayer3Match(new Ipv6MatchBuilder().setIpv6Source(new Ipv6Prefix(IPV6_2 + IP_PREFIX_128)).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.setIpv6SrcAction(new Ipv6Address(IPV6_1))));
+        InstructionBuilder goTo = new InstructionBuilder();
+        goTo.setOrder(1).setInstruction(FlowUtils.gotoTableIns((short) 6));
+        List<Instruction> instructions = new ArrayList<>();
+        instructions.add(apply.build());
+        instructions.add(goTo.build());
+        instructionsBuilder.setInstruction(instructions);
+
+        Flow testFlow = flowCreator(new FlowId(EGRESS_NAT + new IpAddress(new Ipv6Address(IPV6_2)) + "|" +
+                new IpAddress(new Ipv6Address(IPV6_1))), tableId, 80, match, instructionsBuilder.build());
+
+        flows.natFlows((short) 6, endpointL3, 80, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, 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
new file mode 100644 (file)
index 0000000..5d74f72
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 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.egressnat;
+
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.opendaylight.groupbasedpolicy.dto.EpKey;
+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.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.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.List;
+
+import static org.mockito.Mockito.*;
+
+public class EgressNatMapperTest extends MapperUtilsTest {
+
+    private short tableId;
+
+    @Before
+    public void init() {
+        tableId = 5;
+        ctx = mock(OfContext.class);
+        ofWriter = mock(OfWriter.class);
+        endpointManager = mock(EndpointManager.class);
+        policyManager = mock(PolicyManager.class);
+    }
+
+    @Test
+    public void testSyncFlows() {
+        EgressNatMapperFlows flows = mock(EgressNatMapperFlows.class);
+        EgressNatMapper mapper = new EgressNatMapper(ctx, tableId);
+
+        // Endpoint
+        Endpoint endpoint = endpointCreator(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0),
+                new NodeConnectorId(CONNECTOR_1));
+
+        // L3 endpoints
+        EndpointL3 endpointL3 = endpointL3Creator(IPV4_1, IPV4_2, MAC_0, L2, false);
+        List<EndpointL3> endpointsL3 = new ArrayList<>();
+        endpointsL3.add(endpointL3);
+
+        when(ctx.getPolicyManager()).thenReturn(policyManager);
+        when(ctx.getEndpointManager()).thenReturn(endpointManager);
+        when(endpointManager.getL3EndpointsWithNat()).thenReturn(endpointsL3);
+        when(endpointManager.getEndpoint(Mockito.any(EpKey.class))).thenReturn(endpoint);
+
+        // Verify usage
+        mapper.syncFlows(flows, endpoint, ofWriter);
+        verify(flows, times(1)).dropFlow(Mockito.anyInt(), Mockito.anyLong(), eq(ofWriter));
+        verify(flows, times(1)).natFlows(Mockito.anyShort(), Mockito.any(EndpointL3.class),
+                Mockito.anyInt(), eq(ofWriter));
+
+        // Verify order
+        InOrder order = inOrder(ctx, flows);
+        order.verify(flows, times(1)).dropFlow(Mockito.anyInt(), Mockito.anyLong(), eq(ofWriter));
+        order.verify(ctx, times(1)).getPolicyManager();
+        order.verify(flows, times(1)).natFlows(Mockito.anyShort(), Mockito.any(EndpointL3.class),
+                Mockito.anyInt(), eq(ofWriter));
+    }
+}
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
new file mode 100644 (file)
index 0000000..7d74582
--- /dev/null
@@ -0,0 +1,258 @@
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.ingressnat;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+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.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.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 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;
+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.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
+import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction;
+
+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() {
+        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);
+    }
+
+    @Test
+    public void testBaseFlow() {
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(GOTO_DESTINATION_MAPPER), tableId, 50, null,
+                FlowUtils.gotoTableInstructions((short) 2));
+
+        flows.baseFlow((short) 2, 50, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
+    }
+
+    @Test
+    public void testNatFlow_noAugmentation() {
+        EndpointL3 testEndpointL3 = endpointL3Creator(null, null, null, null, false);
+
+        flows.createNatFlow((short) 3, testEndpointL3, null, 60, ofWriter);
+        verifyZeroInteractions(ctx);
+        verifyZeroInteractions(ofWriter);
+    }
+
+    @Test
+    public void testNatFlow() throws Exception {
+        EndpointL3 testEndpointL3 = endpointL3Creator(IPV4_1, IPV4_2, null, null, false);
+        Endpoint testEndpoint = endpointCreator(null, new MacAddress(MAC_0),
+                new NodeConnectorId(CONNECTOR_0));
+
+        when(ctx.getEndpointManager()).thenReturn(endpointManager);
+        when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(tenantCreator());
+        when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
+
+        OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint);
+
+        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));
+        assertNotNull(ordinals);
+
+        List<Instruction> instructions = new ArrayList<>();
+        Action[] ipActions = {FlowUtils.setIpv4DstAction(new Ipv4Address(IPV4_2)),
+                FlowUtils.setDlDstAction(null)};
+        Action[] ordinalsAction = {FlowUtils.nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1)),
+                FlowUtils.nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadTunIdAction(BigInteger.valueOf(2), false)};
+        instructions.add(new InstructionBuilder().setOrder(0)
+                .setInstruction(FlowUtils.applyActionIns(ArrayUtils.addAll(ipActions, ordinalsAction))).build());
+        instructions.add(new InstructionBuilder().setOrder(1).setInstruction(FlowUtils.gotoTableIns((short) 2)).build());
+        InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
+        instructionsBuilder.setInstruction(instructions);
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder.setLayer3Match(new Ipv4MatchBuilder().setIpv4Destination(new Ipv4Prefix(IPV4_1 +
+                IP_PREFIX_32)).build());
+        matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4));
+
+        Flow testFlow = flowCreator(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());
+
+        flows.createNatFlow((short) 2, testEndpointL3, ordinals, 60, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
+    }
+
+    @Test
+    public void testArpFlow_noAugmentation() {
+        EndpointL3 testEndpointL3 = endpointL3Creator(null, null, null, null, false);
+
+        flows.createArpFlow(tenantCreator(), testEndpointL3, 60, ofWriter);
+        verifyZeroInteractions(ctx);
+        verifyZeroInteractions(ofWriter);
+    }
+
+    @Test
+    public void testArpFlow() {
+        EndpointL3 testEndpointL3 = endpointL3Creator(IPV4_1, IPV4_2, MAC_0, null, false);
+        List<Instruction> 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))};
+        instructions.add(new InstructionBuilder().setOrder(0)
+                .setInstruction(FlowUtils.applyActionIns(ArrayUtils.addAll(arpActions))).build());
+        InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
+        instructionsBuilder.setInstruction(instructions);
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP));
+        matchBuilder.setLayer3Match(new ArpMatchBuilder().setArpOp(1).setArpTargetTransportAddress(new Ipv4Prefix(IPV4_1
+                + IP_PREFIX_32)).build());
+        Match match = matchBuilder.build();
+
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, INGRESS_ARP, match),
+                tableId, 60, match, instructionsBuilder.build());
+
+        flows.createArpFlow(tenantCreator(), testEndpointL3, 60, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
+    }
+
+    @Test
+    public void testIngressExternalNatFlow() throws Exception {
+        Endpoint testEndpoint = endpointCreator(new IpAddress(new Ipv6Address(IPV6_1)), new MacAddress(MAC_0),
+                new NodeConnectorId(CONNECTOR_0));
+
+        when(ctx.getEndpointManager()).thenReturn(endpointManager);
+        when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(tenantCreator());
+        when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
+
+        OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint);
+
+        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));
+        assertNotNull(ordinals);
+
+        List<Instruction> instructions = new ArrayList<>();
+        Action[] ordinalsAction = {FlowUtils.nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1)),
+                FlowUtils.nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadTunIdAction(BigInteger.valueOf(2), false)};
+        instructions.add(new InstructionBuilder().setOrder(0)
+                .setInstruction(FlowUtils.applyActionIns(ArrayUtils.addAll(ordinalsAction))).build());
+        instructions.add(new InstructionBuilder().setOrder(1).setInstruction(FlowUtils.gotoTableIns((short) 2)).build());
+        InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
+        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());
+        Match match = matchBuilder.build();
+
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, INBOUND_EXTERNAL_IP, match), tableId, 50, match,
+                instructionsBuilder.build());
+
+        flows.createIngressExternalNatFlows((short) 2, testEndpoint, ordinals, 50, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
+
+    }
+
+    @Test
+    public void testIngressExternalArpFlow() throws Exception {
+        Endpoint testEndpoint = endpointCreator(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0),
+                new NodeConnectorId(CONNECTOR_0));
+
+        when(ctx.getEndpointManager()).thenReturn(endpointManager);
+        when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(tenantCreator());
+        when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
+
+        OrdinalFactory.EndpointFwdCtxOrdinals ordinals = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, testEndpoint);
+
+        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));
+        assertNotNull(ordinals);
+
+        List<Instruction> instructions = new ArrayList<>();
+        Action[] ordinalsAction = {FlowUtils.nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(1)),
+                FlowUtils.nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(0)),
+                FlowUtils.nxLoadTunIdAction(BigInteger.valueOf(2), false)};
+        instructions.add(new InstructionBuilder().setOrder(0)
+                .setInstruction(FlowUtils.applyActionIns(ArrayUtils.addAll(ordinalsAction))).build());
+        instructions.add(new InstructionBuilder().setOrder(1).setInstruction(FlowUtils.gotoTableIns((short) 0)).build());
+        InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
+        instructionsBuilder.setInstruction(instructions);
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(new MacAddress(MAC_0), null, FlowUtils.ARP));
+        Match match = matchBuilder.build();
+
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, INBOUND_EXTERNAL_ARP, match), tableId, 30, match,
+                instructionsBuilder.build());
+
+        flows.createIngressExternalArpFlows((short) 0, testEndpoint, ordinals, 30, ofWriter);
+        verify(ofWriter, times(1)).writeFlow(nodeId, 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
new file mode 100644 (file)
index 0000000..6bad3aa
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015 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.ingressnat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+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.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;
+import java.util.List;
+import java.util.Set;
+
+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);
+        ofWriter = mock(OfWriter.class);
+        endpointManager = mock(EndpointManager.class);
+        policyManager = mock(PolicyManager.class);
+        policyInfo = mock(PolicyInfo.class);
+        tableId = 1;
+    }
+
+    @Test
+    public void testSyncFlows() throws Exception {
+
+        // Endpoints
+        Endpoint endpoint = endpointCreator(new IpAddress(new Ipv4Address(IPV4_1)), new MacAddress(MAC_0),
+                new NodeConnectorId(CONNECTOR_0));
+        List<Endpoint> endpoints = new ArrayList<>();
+        endpoints.add(endpoint);
+
+        // L3 endpoints
+        EndpointL3 endpointL3 = endpointL3Creator(IPV4_1, IPV4_2, MAC_0, L2, false);
+        List<EndpointL3> endpointsL3 = new ArrayList<>();
+        endpointsL3.add(endpointL3);
+
+        // EgKEy set
+        Set<EgKey> egKeys = new HashSet<>();
+        egKeys.add(new EgKey(new TenantId(TENANT_ID), new EndpointGroupId(EPG_ID)));
+
+        when(ctx.getPolicyManager()).thenReturn(policyManager);
+        when(ctx.getTenant(Mockito.any(TenantId.class))).thenReturn(tenantCreator());
+        when(ctx.getEndpointManager()).thenReturn(endpointManager);
+        when(endpointManager.getL3EndpointsWithNat()).thenReturn(endpointsL3);
+        when(endpointManager.getEndpoint(Mockito.any(EpKey.class))).thenReturn(endpoint);
+        when(endpointManager.getEgKeysForEndpoint(Mockito.any(Endpoint.class))).thenReturn(egKeys);
+        when(ctx.getCurrentPolicy()).thenReturn(policyInfo);
+        when(endpointManager.getExtEpsNoLocForGroup(Mockito.any(EgKey.class))).thenReturn(endpoints);
+
+        IngressNatMapperFlows flows = mock(IngressNatMapperFlows.class);
+        IngressNatMapper ingressNatMapper = new IngressNatMapper(ctx, tableId);
+        ingressNatMapper.syncFlows(flows, endpoint, ofWriter);
+
+        // Verify usage
+        verify(flows, times(1)).baseFlow(Mockito.anyShort(), Mockito.anyInt(), eq(ofWriter));
+        verify(flows, times(1)).createNatFlow(Mockito.anyShort(), Mockito.any(EndpointL3.class),
+                Mockito.any(OrdinalFactory.EndpointFwdCtxOrdinals.class), Mockito.anyInt(), eq(ofWriter));
+        verify(flows, times(1)).createArpFlow(Mockito.any(IndexedTenant.class), Mockito.any(EndpointL3.class),
+                Mockito.anyInt(), eq(ofWriter));
+        verify(flows, times(1)).createIngressExternalNatFlows(Mockito.anyShort(), Mockito.any(Endpoint.class),
+                Mockito.any(OrdinalFactory.EndpointFwdCtxOrdinals.class), Mockito.anyInt(), eq(ofWriter));
+        verify(flows, times(1)).createIngressExternalArpFlows(Mockito.anyShort(), Mockito.any(Endpoint.class),
+                Mockito.any(OrdinalFactory.EndpointFwdCtxOrdinals.class), Mockito.anyInt(), eq(ofWriter));
+
+        // Verify order
+        InOrder order = inOrder(ctx, flows);
+        order.verify(ctx, times(1)).getPolicyManager();
+        order.verify(flows, times(1)).baseFlow(Mockito.anyShort(), Mockito.anyInt(), eq(ofWriter));
+        order.verify(flows, times(1)).createNatFlow(Mockito.anyShort(), Mockito.any(EndpointL3.class),
+                Mockito.any(OrdinalFactory.EndpointFwdCtxOrdinals.class), Mockito.anyInt(), eq(ofWriter));
+        order.verify(ctx, times(1)).getTenant(Mockito.any(TenantId.class));
+        order.verify(flows, times(1)).createArpFlow(Mockito.any(IndexedTenant.class), Mockito.any(EndpointL3.class),
+                Mockito.anyInt(), eq(ofWriter));
+        order.verify(ctx, times(1)).getCurrentPolicy();
+        order.verify(ctx, times(1)).getEndpointManager();
+        order.verify(flows, times(1)).createIngressExternalNatFlows(Mockito.anyShort(), Mockito.any(Endpoint.class),
+                Mockito.any(OrdinalFactory.EndpointFwdCtxOrdinals.class), Mockito.anyInt(), eq(ofWriter));
+        order.verify(flows, times(1)).createIngressExternalArpFlows(Mockito.anyShort(), Mockito.any(Endpoint.class),
+                Mockito.any(OrdinalFactory.EndpointFwdCtxOrdinals.class), Mockito.anyInt(), eq(ofWriter));
+    }
+}
index 098b895a6f7b31cbc4b3e98b3d1ec02c403c00ab..362804108324995d21bfe727212ff262ce49e7c4 100644 (file)
@@ -5,6 +5,7 @@ import org.junit.Test;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
+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.inet.types.rev100924.Ipv4Prefix;
@@ -13,26 +14,14 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 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;
 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.Instructions;
 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.L2FloodDomainId;
-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.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.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.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.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;
@@ -42,39 +31,27 @@ import java.util.List;
 
 import static org.mockito.Mockito.*;
 
-public class PortSecurityFlowsTest {
+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 IPV4_1 = "170.0.0.1";
-    private static final String MAC_0 = "00:00:00:00:00:00";
-    private static final String MAC_1 = "00:00:00:00:00:01";
-    private static final String CONNECTOR_0 = "0";
-    private static final String CONNECTOR_1 = "1";
-    private static final String IP_PREFIX_32 = "/32";
-    private static final String IP_PREFIX_128 = "/128";
     private static final String L3 = "L3";
-    private static final String IPV6 = "2000:db80:85a3:08ba:0947:8a2e:3a70:7334";
-    private static final String DHCP_IP = "255.255.255.255";
-    private static final String L2 = "L2";
     private static final String DHCP = "dhcp";
     private static final String ALLOW_EXTERNAL = "allowExternal";
     private static final String ALLOW_EXTERNAL_POP_VLAN = "allowExternalPopVlan";
-    private final NodeId nodeId = new NodeId("dummy node");
-    private final Short tableId = 0;
     private PortSecurityFlows flows;
-    private OfWriter ofWriter;
 
     @Before
     public void init() {
+        tableId = 0;
         ofWriter = mock(OfWriter.class);
         flows = new PortSecurityFlows(nodeId, tableId);
     }
 
     @Test
     public void testDropFlow_noEthertype() {
-        Flow testFlow = flowCreator(new FlowId(DROP_ALL), 100, null, FlowUtils.dropInstructions());
+        Flow testFlow = flowCreator(new FlowId(DROP_ALL), tableId, 100, null, FlowUtils.dropInstructions());
 
         flows.dropFlow(100, null, ofWriter);
         verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
@@ -85,7 +62,7 @@ public class PortSecurityFlowsTest {
         MatchBuilder matchBuilder = new MatchBuilder();
         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv4));
         Match match = matchBuilder.build();
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), 100, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
                 FlowUtils.dropInstructions());
 
         flows.dropFlow(100, FlowUtils.IPv4, ofWriter);
@@ -97,7 +74,7 @@ public class PortSecurityFlowsTest {
         MatchBuilder matchBuilder = new MatchBuilder();
         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.IPv6));
         Match match = matchBuilder.build();
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), 100, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
                 FlowUtils.dropInstructions());
 
         flows.dropFlow(100, FlowUtils.IPv6, ofWriter);
@@ -109,7 +86,7 @@ public class PortSecurityFlowsTest {
         MatchBuilder matchBuilder = new MatchBuilder();
         matchBuilder.setEthernetMatch(FlowUtils.ethernetMatch(null, null, FlowUtils.ARP));
         Match match = matchBuilder.build();
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), 100, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DROP, match), tableId, 100, match,
                 FlowUtils.dropInstructions());
 
         flows.dropFlow(100, FlowUtils.ARP, ofWriter);
@@ -122,7 +99,7 @@ public class PortSecurityFlowsTest {
         MatchBuilder matchBuilder = new MatchBuilder();
         matchBuilder.setInPort(new NodeConnectorId(String.valueOf(VXLAN_PORT)));
         Match match = matchBuilder.build();
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW, match), 300, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW, match), tableId, 300, match,
                 FlowUtils.gotoTableInstructions((short) 2));
 
         flows.allowFromTunnelFlow((short) 2, 300, new NodeConnectorId(CONNECTOR_0), ofWriter);
@@ -136,7 +113,7 @@ public class PortSecurityFlowsTest {
         MatchBuilder matchBuilder = new MatchBuilder();
         matchBuilder.setInPort(new NodeConnectorId(String.valueOf(VXLAN_PORT)));
         Match match = matchBuilder.build();
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW, match), 300, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW, match), tableId, 300, match,
                 FlowUtils.gotoTableInstructions((short) 2));
 
         flows.allowFromTunnelFlow((short) 2, 300, new NodeConnectorId(CONNECTOR_1), ofWriter);
@@ -158,7 +135,7 @@ public class PortSecurityFlowsTest {
                 .setInPort(connectorId);
         Match match = matchBuilder.build();
 
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L3, match), 100, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match,
                 FlowUtils.gotoTableInstructions((short) 2));
 
         flows.l3Flow((short) 2, testEp, new NodeConnectorId(CONNECTOR_0), new MacAddress(MAC_0), 100, false, ofWriter);
@@ -179,7 +156,7 @@ public class PortSecurityFlowsTest {
                 .setInPort(connectorId);
         Match match = matchBuilder.build();
 
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L3, match), 100, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match,
                 FlowUtils.gotoTableInstructions((short) 2));
 
         flows.l3Flow((short) 2, testEp, new NodeConnectorId(CONNECTOR_1), new MacAddress(MAC_1), 100, true, ofWriter);
@@ -188,7 +165,7 @@ public class PortSecurityFlowsTest {
 
     @Test
     public void testL3flow_ipv6() {
-        IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6));
+        IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1));
         MacAddress macAddress = new MacAddress(MAC_0);
         NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_0);
         Endpoint testEp = endpointCreator(ipAddress, macAddress, connectorId);
@@ -200,7 +177,7 @@ public class PortSecurityFlowsTest {
                 .setInPort(connectorId);
         Match match = matchBuilder.build();
 
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L3, match), 100, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L3, match), tableId, 100, match,
                 FlowUtils.gotoTableInstructions((short) 2));
 
         flows.l3Flow((short) 2, testEp, new NodeConnectorId(CONNECTOR_0), new MacAddress(MAC_0), 100, false, ofWriter);
@@ -209,7 +186,7 @@ public class PortSecurityFlowsTest {
 
     @Test
     public void testL3flow_ipv6Arp() {
-        IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6));
+        IpAddress ipAddress = new IpAddress(new Ipv6Address(IPV6_1));
         MacAddress macAddress = new MacAddress(MAC_1);
         NodeConnectorId connectorId = new NodeConnectorId(CONNECTOR_1);
         Endpoint testEp = endpointCreator(ipAddress, macAddress, connectorId);
@@ -231,7 +208,7 @@ public class PortSecurityFlowsTest {
                 .setInPort(connectorId);
         Match match = matchBuilder.build();
 
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DHCP, match), 50, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, DHCP, match), tableId, 50, match,
                 FlowUtils.gotoTableInstructions((short) 2));
 
         flows.l3DhcpDoraFlow((short) 2, new NodeConnectorId(CONNECTOR_1), new MacAddress(MAC_1), 50, ofWriter);
@@ -248,7 +225,7 @@ public class PortSecurityFlowsTest {
                 .setInPort(connectorId);
         Match match = matchBuilder.build();
 
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L2, match), 100, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, L2, match), tableId, 100, match,
                 FlowUtils.gotoTableInstructions((short) 2));
 
         flows.l2flow((short) 2, new NodeConnectorId(CONNECTOR_0), new MacAddress(MAC_0), 100, ofWriter);
@@ -273,7 +250,7 @@ public class PortSecurityFlowsTest {
 
         List<L2FloodDomain> l2FloodDomains = l2FloodDomainsCreator();
 
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW_EXTERNAL_POP_VLAN, match), 200, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW_EXTERNAL_POP_VLAN, match), tableId, 200, match,
                 instructionsBuilder.build());
 
         flows.popVlanTagsOnExternalPortFlows((short) 0, connectorId, l2FloodDomains, 200, ofWriter);
@@ -288,52 +265,9 @@ public class PortSecurityFlowsTest {
         matchBuilder.setInPort(connectorId);
         Match match = matchBuilder.build();
 
-        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW_EXTERNAL, match), 250, match,
+        Flow testFlow = flowCreator(FlowIdUtils.newFlowId(tableId, ALLOW_EXTERNAL, match), tableId, 250, match,
                 FlowUtils.gotoTableInstructions((short) 2));
         flows.allowFromExternalPortFlow((short) 2, connectorId, 250, ofWriter);
         verify(ofWriter, times(1)).writeFlow(nodeId, tableId, testFlow);
     }
-
-    private Flow flowCreator(FlowId flowId, int priority, Match match, Instructions instructions) {
-        FlowBuilder flowBuilder = FlowUtils.base(tableId);
-        flowBuilder.setId(flowId)
-                .setPriority(priority)
-                .setMatch(match)
-                .setInstructions(instructions);
-
-        return flowBuilder.build();
-    }
-
-    private Endpoint endpointCreator(IpAddress ip, MacAddress mac, NodeConnectorId nodeConnectorId) {
-        EndpointBuilder endpointBuilder = new EndpointBuilder();
-
-        // Set L3 address
-        List<L3Address> l3Addresses = new ArrayList<>();
-        L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
-        l3AddressBuilder.setIpAddress(ip);
-        l3Addresses.add(l3AddressBuilder.build());
-        endpointBuilder.setL3Address(l3Addresses);
-
-        // Set Mac address
-        endpointBuilder.setMacAddress(new MacAddress(mac));
-
-        // Augment node connector
-        OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
-        ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(nodeConnectorId));
-        endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
-
-        return endpointBuilder.build();
-    }
-
-    private List<L2FloodDomain> l2FloodDomainsCreator() {
-        SegmentationBuilder segmentationBuilder = new SegmentationBuilder();
-        segmentationBuilder.setSegmentationId(1);
-        List<L2FloodDomain> l2FloodDomains = new ArrayList<>();
-        L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder();
-        l2FloodDomainBuilder.setId(new L2FloodDomainId("l2id"));
-        l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build());
-        l2FloodDomains.add(l2FloodDomainBuilder.build());
-        return l2FloodDomains;
-    }
-
 }
index 367655c50f0053570d750f2295825b0e1a63b1db..66c915c58b157c01decff7273650083d83fbcc42 100644 (file)
@@ -4,54 +4,29 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.InOrder;
 import org.mockito.Mockito;
-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.PolicyManager;
 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
-import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowTableTest;
+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.L2FloodDomainId;
 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.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.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.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.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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlanGpe;
 
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import static org.mockito.Mockito.*;
 
-public class PortSecurityTest extends FlowTableTest {
-
-    private static final String IPV4_1 = "170.0.0.1";
-    private static final String MAC_0 = "00:00:00:00:00:00";
-    private static final String CONNECTOR_0 = "0";
-    private static final String CONNECTOR_1 = "1";
-    private final NodeId nodeId = new NodeId("dummy node");
-    private OfContext ctx;
-    private OfWriter ofWriter;
-    private SwitchManager switchManager;
-    private PolicyManager policyManager;
-    private EndpointManager endpointManager;
+public class PortSecurityTest extends MapperUtilsTest {
 
     @Before
     public void init() {
@@ -136,57 +111,4 @@ public class PortSecurityTest extends FlowTableTest {
         order.verify(flows, times(1)).allowFromExternalPortFlow(Mockito.anyShort(), Mockito.any(NodeConnectorId.class),
                 Mockito.anyInt(), eq(ofWriter));
     }
-
-
-    private Endpoint endpointCreator(IpAddress ip, MacAddress mac, NodeConnectorId nodeConnectorId) {
-        EndpointBuilder endpointBuilder = new EndpointBuilder();
-
-        // Set L3 address
-        List<L3Address> l3Addresses = new ArrayList<>();
-        L3AddressBuilder l3AddressBuilder = new L3AddressBuilder();
-        l3AddressBuilder.setIpAddress(ip);
-        l3Addresses.add(l3AddressBuilder.build());
-        endpointBuilder.setL3Address(l3Addresses);
-
-        // Set Mac address
-        endpointBuilder.setMacAddress(new MacAddress(mac));
-
-        // Augment node connector
-        OfOverlayContextBuilder ofOverlayContextBuilder = new OfOverlayContextBuilder();
-        ofOverlayContextBuilder.setNodeConnectorId(new NodeConnectorId(nodeConnectorId));
-        endpointBuilder.addAugmentation(OfOverlayContext.class, ofOverlayContextBuilder.build());
-
-        return endpointBuilder.build();
-    }
-
-    private IndexedTenant tenantCreator() {
-        TenantBuilder tenantBuilder = new TenantBuilder();
-        tenantBuilder.setId(new TenantId("dummy tenant"));
-
-        // Set forwarding context
-        SegmentationBuilder segmentationBuilder = new SegmentationBuilder();
-        segmentationBuilder.setSegmentationId(1);
-        List<L2FloodDomain> l2FloodDomains = new ArrayList<>();
-        L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder();
-        l2FloodDomainBuilder.setId(new L2FloodDomainId("l2id"));
-        l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build());
-        l2FloodDomains.add(l2FloodDomainBuilder.build());
-        ForwardingContextBuilder forwardingContextBuilder = new ForwardingContextBuilder();
-        forwardingContextBuilder.setL2FloodDomain(l2FloodDomains);
-        tenantBuilder.setForwardingContext(forwardingContextBuilder.build());
-
-        return new IndexedTenant(tenantBuilder.build());
-    }
-
-    private List<L2FloodDomain> l2FloodDomainsCreator() {
-        SegmentationBuilder segmentationBuilder = new SegmentationBuilder();
-        segmentationBuilder.setSegmentationId(1);
-        List<L2FloodDomain> l2FloodDomains = new ArrayList<>();
-        L2FloodDomainBuilder l2FloodDomainBuilder = new L2FloodDomainBuilder();
-        l2FloodDomainBuilder.setId(new L2FloodDomainId("l2id"));
-        l2FloodDomainBuilder.addAugmentation(Segmentation.class, segmentationBuilder.build());
-        l2FloodDomains.add(l2FloodDomainBuilder.build());
-        return l2FloodDomains;
-    }
-
 }
\ No newline at end of file