Initial implementation for dynamic SNAT 93/52493/7
authorTomas Cechvala <tcechval@cisco.com>
Tue, 28 Feb 2017 09:25:53 +0000 (10:25 +0100)
committerTomas Cechvala <tcechval@cisco.com>
Thu, 2 Mar 2017 17:43:51 +0000 (17:43 +0000)
allocation pools is needed in an external network
 -> VPP renderer will use external subnet as a pool
    for dynamic SNAT.
     - isTenant = false
     - allocationPool is specified
 -> traffic passing through an interface set to
    'outside NAT' will be automatically translated

Change-Id: I18077d0fa31ae1ae3b2fde13aa12c2d41c3fdecb
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
domain-extensions/l2-l3/src/main/yang/l2-l3-forwarding.yang
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/util/NetworkUtils.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAwareDataStoreTest.java
neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/NeutronMapperAssert.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/nat/NatManager.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/nat/NatUtil.java
renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java

index 5d8f3a61fbbeb8506c6664c44e05c802fa64a8e0..b0b82af4e2d1296d87d1820d1e37937323a0a075 100644 (file)
@@ -78,6 +78,21 @@ module l2-l3-forwarding {
                     }
                 }
             }
+            list allocation-pool {
+                description "Allocation pool of assignable addresses.";
+                key "first last";
+                leaf first {
+                    type string;
+                }
+                leaf last {
+                    type string;
+                }
+            }
+            leaf is-tenant {
+                description "Subnet is used as tenant network.";
+                type boolean;
+                default "true";
+            }
         }
     }
 
index cb177af8fb36c11cda2d42a00ab489037fb55b99..c46cf2d3010fe39ea155fc6083b2f4b9da8b8598 100644 (file)
@@ -175,7 +175,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
             rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
             // set virtual router IP for subnet
             NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(
-                    routerPortSubnet, portIpWithSubnet.getIpAddress());
+                    routerPortSubnet, neutron);
             rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain);
 
             // does the same for tenant forwarding domains
@@ -589,7 +589,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 .build();
             rwTx.merge(LogicalDatastoreType.CONFIGURATION,
                     L2L3IidFactory.l2BridgeDomainIid(tenantId, fwdCtx.getContextId()), fwdCtx);
-            NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null);
+            NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, newNeutron);
             rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()),
                     subnet);
             unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
index fc7c1675cc55820484de7ae4e38f9a1550dff270..6d70dcd2fbb44ec514790384e7066cbfd73bd4c0 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -29,10 +32,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwarding;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwardingBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.SubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.subnet.AllocationPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.subnet.AllocationPoolBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -80,8 +87,7 @@ public class NeutronSubnetAware implements
 
         NetworkDomain subnetDomain = null;
         if (NetworkUtils.isProviderPhysicalNetwork(networkOfSubnet)) {
-            // add virtual router IP only in case it is provider physical network
-            subnetDomain = createSubnet(neutronSubnet, neutronSubnet.getGatewayIp());
+            subnetDomain = createSubnet(neutronSubnet, neutron);
             IpAddress gatewayIp = neutronSubnet.getGatewayIp();
             boolean registeredDefaultRoute = epRegistrator.registerExternalL3PrefixEndpoint(MappingUtils.DEFAULT_ROUTE,
                     new L3ContextId(neutronSubnet.getNetworkId().getValue()), gatewayIp, tenantId);
@@ -92,9 +98,7 @@ public class NeutronSubnetAware implements
                 return;
             }
         } else {
-            // virtual router IP is not set and it will be set when router gateway port is set
-            // or when a router port is attached to a network
-            subnetDomain = createSubnet(neutronSubnet, null);
+            subnetDomain = createSubnet(neutronSubnet, neutron);
         }
         processTenantSubnet(neutronSubnet, networkOfSubnet, tenantId, rwTx);
         rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain, true);
@@ -103,10 +107,54 @@ public class NeutronSubnetAware implements
 
     public static NetworkDomain createSubnet(
             org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet subnet,
-            IpAddress virtualRouterIp) {
+            Neutron neutron) {
         SubnetBuilder sb = new SubnetBuilder();
         sb.setIpPrefix(subnet.getCidr());
-        sb.setVirtualRouterIp(virtualRouterIp);
+        if (neutron.getPorts() != null && neutron.getPorts().getPort() != null) {
+            for (Port port : neutron.getPorts().getPort()) {
+                if (port.getFixedIps() == null || !port.getFixedIps()
+                    .stream()
+                    .filter(fi -> fi.getSubnetId().equals(subnet.getUuid()))
+                    .findFirst()
+                    .isPresent()) {
+                    continue;
+                }
+                if (neutron.getRouters() != null && neutron.getRouters().getRouter() != null && neutron.getRouters()
+                    .getRouter()
+                    .stream()
+                    .filter(r -> !r.getUuid().getValue().equals(port.getDeviceOwner()))
+                    .findFirst()
+                    .isPresent()) {
+                    // virtual router IP is set when a router port is attached to a network
+                    sb.setVirtualRouterIp(subnet.getGatewayIp());
+                } else if (neutron.getNetworks() != null && neutron.getNetworks().getNetwork() != null && neutron
+                    .getNetworks()
+                    .getNetwork()
+                    .stream()
+                    .filter(net -> net.getUuid().equals(port.getNetworkId()))
+                    .filter(net -> net.getAugmentation(NetworkProviderExtension.class) != null)
+                    .filter(net -> net.getAugmentation(NetworkProviderExtension.class).getPhysicalNetwork() != null)
+                    .findFirst()
+                    .isPresent()) {
+                    // add virtual router IP only in case it is provider physical network
+                    sb.setVirtualRouterIp(subnet.getGatewayIp());
+                }
+            }
+        }
+        Optional<Network> potentialNetwork =
+                NetworkUtils.findNetwork(subnet.getNetworkId(), neutron.getNetworks());
+        if (potentialNetwork.isPresent()) {
+            sb.setIsTenant(NetworkUtils.isTenantNetwork(potentialNetwork.get()));
+        }
+        if (subnet.getAllocationPools() != null) {
+            List<AllocationPool> pools = subnet.getAllocationPools()
+                .stream()
+                .map(s -> new AllocationPoolBuilder().setFirst(s.getStart().getIpv4Address().getValue())
+                    .setLast(s.getEnd().getIpv4Address().getValue())
+                    .build())
+                .collect(Collectors.toList());
+            sb.setAllocationPool(pools);
+        }
         NetworkDomainBuilder ndb = new NetworkDomainBuilder();
         if (!Strings.isNullOrEmpty(subnet.getName())) {
             try {
index 237f105d0af7e2698defa2313898aef92bee3772..eff8541e5a4d35b81a1456049f6930d12e53a62b 100644 (file)
@@ -51,6 +51,10 @@ public class NetworkUtils {
         return Optional.absent();
     }
 
+    public static boolean isTenantNetwork(Network network) {
+        return getPhysicalNetwork(network).isEmpty();
+    }
+
     public static boolean isProviderPhysicalNetwork(Network network) {
         return (!isRouterExternal(network) && !getPhysicalNetwork(network).isEmpty());
     }
index d5f7c6b16335c40a88dfc552639d0826e37fa066..cd5f3099eb9852ff043c581c8796b97d914af1dd 100644 (file)
@@ -14,7 +14,6 @@ import static org.mockito.Mockito.when;
 
 import java.util.List;
 
-import com.google.common.collect.ImmutableList;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -43,6 +42,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.s
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetBuilder;
 
+import com.google.common.collect.ImmutableList;
+
 public class NeutronPortAwareDataStoreTest extends NeutronMapperDataBrokerTest {
 
     private final Uuid tenantUuid = new Uuid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
@@ -188,10 +189,10 @@ public class NeutronPortAwareDataStoreTest extends NeutronMapperDataBrokerTest {
             .setFixedIps(ImmutableList.of(portIpWithSubnet))
             .build();
         portAware.onCreated(port, neutron);
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, port, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, port, subnet, neutron);
 
         portAware.onDeleted(port, neutron, neutron);
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, port, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, port, subnet, neutron);
         NeutronMapperAssert.assertPortNotExists(dataBroker, port.getUuid());
     }
 
@@ -204,7 +205,7 @@ public class NeutronPortAwareDataStoreTest extends NeutronMapperDataBrokerTest {
         Subnet subnet = subnets.getSubnet().get(0);
         Port port = newBasePort().setDeviceOwner(PortUtils.DEVICE_OWNER_ROUTER_IFACE).build();
         portAware.onCreated(port, neutron);
-        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, port, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, port, subnet, neutron);
     }
 
     @Test
index 0712d54961c761ba39ada3971dd47b515077b3e7..e9b63dc74a41df07545c5e9aa3b6d536a6cb4113 100644 (file)
@@ -15,7 +15,6 @@ import static org.mockito.Mockito.when;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-import com.google.common.collect.ImmutableList;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -42,6 +41,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.s
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetBuilder;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+import com.google.common.collect.ImmutableList;
+
 public class NeutronSubnetAwareDataStoreTest extends NeutronMapperDataBrokerTest {
 
     private static final Uuid tenantUuid = new Uuid("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
@@ -122,7 +123,7 @@ public class NeutronSubnetAwareDataStoreTest extends NeutronMapperDataBrokerTest
 
         subnetAware.onCreated(subnet, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, neutron);
     }
 
     @Test
@@ -133,7 +134,7 @@ public class NeutronSubnetAwareDataStoreTest extends NeutronMapperDataBrokerTest
 
         subnetAware.onCreated(subnet, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, tenantUuid, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, tenantUuid, subnet, neutron);
     }
 
     @Test
@@ -145,12 +146,12 @@ public class NeutronSubnetAwareDataStoreTest extends NeutronMapperDataBrokerTest
 
         subnetAware.onCreated(subnet, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, ipAddress);
-        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, tenantUuid, subnet2, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, neutron);
+        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, tenantUuid, subnet2, neutron);
 
         subnetAware.onUpdated(subnet, subnet2, neutron, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet2, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet2, neutron);
     }
 
     @Test
@@ -162,13 +163,12 @@ public class NeutronSubnetAwareDataStoreTest extends NeutronMapperDataBrokerTest
 
         subnetAware.onCreated(subnet, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, neutron);
 
         subnetAware.onDeleted(subnet, neutron, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, tenantUuid, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainNotExists(dataBroker, tenantUuid, subnet, neutron);
     }
-
     @Test
     public void testOnDeleted_wrongSubnet() {
 
@@ -178,11 +178,11 @@ public class NeutronSubnetAwareDataStoreTest extends NeutronMapperDataBrokerTest
 
         subnetAware.onCreated(subnet, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, neutron);
 
         subnetAware.onDeleted(subnet2, neutron, neutron);
 
-        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, ipAddress);
+        NeutronMapperAssert.assertNetworkDomainExists(dataBroker, tenantUuid, subnet, neutron);
     }
 
 }
index d3b774ed08f318ec14fba4c98f72a935e45eeef2..5098cb3f3f50c6de45c84304409ca6d31924ba92 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -55,35 +56,35 @@ public class NeutronMapperAssert {
         return portOptional;
     }
 
-    public static void assertNetworkDomainExists(DataBroker dataBroker, Port port, Subnet subnet, IpAddress ipAddress) {
+    public static void assertNetworkDomainExists(DataBroker dataBroker, Port port, Subnet subnet, Neutron neutron) {
         Optional<NetworkDomain> opt =
-                getNetworkDomainOptional(dataBroker, port.getTenantId(), ipAddress, subnet);
+                getNetworkDomainOptional(dataBroker, port.getTenantId(), neutron, subnet);
         assertTrue(opt.isPresent());
     }
 
     public static void assertNetworkDomainNotExists(DataBroker dataBroker, Port port, Subnet subnet,
-            IpAddress ipAddress) {
+            Neutron neutron) {
         Optional<NetworkDomain> opt =
-                getNetworkDomainOptional(dataBroker, port.getTenantId(), ipAddress, subnet);
+                getNetworkDomainOptional(dataBroker, port.getTenantId(), neutron, subnet);
         assertFalse(opt.isPresent());
     }
 
     public static void assertNetworkDomainExists(DataBroker dataBroker, Uuid tenantUuid, Subnet subnet,
-            IpAddress ipAddress) {
-        Optional<NetworkDomain> opt = getNetworkDomainOptional(dataBroker, tenantUuid, ipAddress, subnet);
+            Neutron neutron) {
+        Optional<NetworkDomain> opt = getNetworkDomainOptional(dataBroker, tenantUuid, neutron, subnet);
         assertTrue(opt.isPresent());
     }
 
     public static void assertNetworkDomainNotExists(DataBroker dataBroker, Uuid tenantUuid, Subnet subnet,
-            IpAddress ipAddress) {
-        Optional<NetworkDomain> opt = getNetworkDomainOptional(dataBroker, tenantUuid, ipAddress, subnet);
+            Neutron neutron) {
+        Optional<NetworkDomain> opt = getNetworkDomainOptional(dataBroker, tenantUuid, neutron, subnet);
         assertFalse(opt.isPresent());
     }
 
     private static Optional<NetworkDomain> getNetworkDomainOptional(DataBroker dataBroker, Uuid tenantUuid,
-            IpAddress ipAddress, Subnet subnet) {
+            Neutron neutron, Subnet subnet) {
         InstanceIdentifier<NetworkDomain> iid;
-        NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(subnet, ipAddress);
+        NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(subnet, neutron);
         TenantId tenantId = new TenantId(tenantUuid.getValue());
         iid = L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId());
         Optional<NetworkDomain> optional;
index 1564a560e909b816c513c7a281a41ff41df0907d..a5821228beda73aa7e1e89f1410cad4f5ebaaeeb 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;\r
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext;\r
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;\r
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;\r
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
@@ -38,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev1509
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.MappingTableBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntry;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPool;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.VppInterfaceAugmentation;\r
@@ -117,7 +119,7 @@ public class NatManager {
     }\r
 \r
     public ListenableFuture<Void> submitNatChanges(List<InstanceIdentifier<PhysicalInterface>> physIfacesIid,\r
-            List<MappingEntryBuilder> natEntries, boolean add) {\r
+            List<MappingEntryBuilder> natEntries, PolicyContext policyCtx, boolean add) {\r
         List<ListenableFuture<Void>> submitedFutures = new ArrayList<>();\r
         for (InstanceIdentifier<PhysicalInterface> iidPhysIface : physIfacesIid) {\r
             InstanceIdentifier<?> nodeIid = iidPhysIface.firstKeyOf(RendererNode.class).getNodePath();\r
@@ -139,9 +141,9 @@ public class NatManager {
                             }\r
                             if (add) {\r
                                 LOG.trace("Setting outbound NAT on interface {}.", iidPhysIface.getPathArguments());\r
-                                NatUtil.setOutboundInterface(readIface.get(), rwTx);\r
+                                NatUtil.setOutboundInterface(readIface.get(), rwTx); \r
                                 rwTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getNatInstanceIid(id),\r
-                                        buildNatInstance(natEntries));\r
+                                        buildNatInstance(natEntries, NatUtil.resolveDynamicNat(policyCtx)));\r
                             } else {\r
                                 LOG.trace("UNsetting outbound NAT on interface {}.", iidPhysIface.getPathArguments());\r
                                 NatUtil.unsetOutboundInterface(readIface.get(), rwTx);\r
@@ -164,7 +166,7 @@ public class NatManager {
         return Futures.immediateFuture(null);\r
     }\r
 \r
-    private NatInstance buildNatInstance(List<MappingEntryBuilder> natEntries) {\r
+    private NatInstance buildNatInstance(List<MappingEntryBuilder> natEntries, List<ExternalIpAddressPool> poolEntries) {\r
         AtomicInteger ai = new AtomicInteger();\r
          List<MappingEntry> mappingEntries = natEntries.stream().map(me -> {\r
             int value = ai.get();\r
@@ -172,6 +174,6 @@ public class NatManager {
             return me.setIndex((long) value).build();\r
         }).collect(Collectors.toList());\r
         MappingTable mappingTable = new MappingTableBuilder().setMappingEntry(mappingEntries).build();\r
-        return new NatInstanceBuilder().setId(id).setMappingTable(mappingTable).build();\r
+        return new NatInstanceBuilder().setId(id).setExternalIpAddressPool(poolEntries).setMappingTable(mappingTable).build();\r
     }\r
 }\r
index de4f83cd03ee25f7f2d3061251082aa6fa373078..c2fff1cae300230be05e7ede89c29e5e59f0dd68 100644 (file)
@@ -8,10 +8,28 @@
 \r
 package org.opendaylight.groupbasedpolicy.renderer.vpp.nat;\r
 \r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+\r
+import javax.annotation.Nonnull;\r
+import javax.annotation.Nullable;\r
+\r
+import org.apache.commons.net.util.SubnetUtils;\r
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext;\r
 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPool;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPoolBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentRenderer;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.subnet.AllocationPool;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.RendererForwardingByTenant;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.forwarding.renderer.forwarding.by.tenant.RendererNetworkDomain;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev161214.NatInterfaceAugmentation;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev161214._interface.nat.attributes.Nat;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev161214._interface.nat.attributes.NatBuilder;\r
@@ -41,4 +59,47 @@ public class NatUtil {
     public static InstanceIdentifier<Nat> buildNatIid(InstanceIdentifier<Interface> ifaceIid) {\r
         return ifaceIid.builder().augmentation(NatInterfaceAugmentation.class).child(Nat.class).build();\r
     }\r
+\r
+    public static List<ExternalIpAddressPool> resolveDynamicNat(@Nonnull PolicyContext policyCtx) {\r
+        List<RendererForwardingByTenant> rendererForwardingByTenant =\r
+                policyCtx.getPolicy().getConfiguration().getRendererForwarding().getRendererForwardingByTenant();\r
+        Map<Long, Ipv4Prefix> hm = new HashMap<>();\r
+        for (RendererForwardingByTenant rft : rendererForwardingByTenant) {\r
+            for (RendererNetworkDomain rnd : rft.getRendererNetworkDomain()) {\r
+                SubnetAugmentRenderer subnet = rnd.getAugmentation(SubnetAugmentRenderer.class);\r
+                if (subnet.getSubnet() != null && !subnet.getSubnet().isIsTenant()\r
+                        && subnet.getSubnet().getAllocationPool() != null) {\r
+                    for (AllocationPool pool : subnet.getSubnet().getAllocationPool()) {\r
+                        if (subnet.getSubnet().getIpPrefix().getIpv4Prefix() != null) {\r
+                            hm.putAll(resolveIpv4Prefix(subnet.getSubnet().getIpPrefix().getIpv4Prefix(),\r
+                                    pool.getFirst(), pool.getLast()));\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        List<ExternalIpAddressPool> extIps = new ArrayList<>();\r
+        for (Entry<Long, Ipv4Prefix> entry : hm.entrySet()) {\r
+            new ExternalIpAddressPoolBuilder().setPoolId(entry.getKey()).setExternalIpPool(entry.getValue()).build();\r
+        }\r
+        return extIps;\r
+    }\r
+\r
+    private static Map<Long,Ipv4Prefix> resolveIpv4Prefix(@Nonnull Ipv4Prefix prefix, @Nonnull String first,\r
+            @Nullable String last) {\r
+        SubnetUtils subnet = new SubnetUtils(prefix.getValue());\r
+        Map<Long,Ipv4Prefix> ext = new HashMap<>();\r
+        int min = subnet.getInfo().asInteger(first);\r
+        for (String addr : subnet.getInfo().getAllAddresses()) {\r
+            int asInt = subnet.getInfo().asInteger(addr);\r
+            if (asInt < min) {\r
+                continue;\r
+            }\r
+            ext.put(Long.valueOf(asInt), new Ipv4Prefix(addr + "/32"));\r
+            if (last == null || subnet.getInfo().asInteger(addr) > subnet.getInfo().asInteger(last)) {\r
+                break;\r
+            }\r
+        }\r
+        return ext;\r
+    }\r
 }\r
index c69b82179213581c641551f3af11ed25fe57a4ec..2120b5c0da79824ffb29f35f65382c5823de3b20 100644 (file)
@@ -333,7 +333,7 @@ public final class ForwardingManager {
                 for (RendererForwardingByTenant fwd : cfg.getRendererForwarding().getRendererForwardingByTenant()) {
                     List<InstanceIdentifier<PhysicalInterface>> physIfacesIid =
                         resolvePhysicalInterfacesForNat(fwd.getRendererNetworkDomain());
-                    natManager.submitNatChanges(physIfacesIid, natEntries, true);
+                    natManager.submitNatChanges(physIfacesIid, natEntries, policyCtx, true);
                 }
             }
         }
@@ -352,7 +352,7 @@ public final class ForwardingManager {
                 for (RendererForwardingByTenant fwd : cfg.getRendererForwarding().getRendererForwardingByTenant()) {
                     List<InstanceIdentifier<PhysicalInterface>> physIfacesIid =
                         resolvePhysicalInterfacesForNat(fwd.getRendererNetworkDomain());
-                    natManager.submitNatChanges(physIfacesIid, natEntries, false);
+                    natManager.submitNatChanges(physIfacesIid, natEntries, policyCtx, false);
                 }
             }
         }