Bug 3424: Adding support for L2 External Networks. 12/22512/4
authorThomas Bachman <tbachman@yahoo.com>
Thu, 11 Jun 2015 21:21:35 +0000 (17:21 -0400)
committerThomas Bachman <tbachman@yahoo.com>
Mon, 15 Jun 2015 20:53:55 +0000 (20:53 +0000)
This patch is preparation for the rest of the fixes
to support L2 External networks. It moves the creation
of the L3 Endpoint for the gateway from when the gateway
port is attached to the router to when the subnet is
created.

Change-Id: Ieadf3b11604cb3378066e05b4ddf1b68205419d3
Signed-off-by: Thomas Bachman <tbachman@yahoo.com>
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/gbp/util/NeutronGbpIidFactory.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java
neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSubnetAware.java
neutron-mapper/src/main/yang/neutron-gbp-mapper.yang

index e06f7b23bf56067eeb5dfb1e1a23cf8c46b182fb..8b02c6c26a58f351c4621492e43be4b926020a85 100644 (file)
@@ -3,6 +3,7 @@ package org.opendaylight.groupbasedpolicy.neutron.gbp.util;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.FloatingIpAssociationMappings;
@@ -27,12 +28,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gb
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.router.gateway.ports.EndpointByRouterGatewayPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.router.gateway.ports.EndpointByRouterGatewayPortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ExternalGatewaysAsL3Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ExternalNetworksByL2FloodDomains;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.FloatingIpPortsByEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.PortsByEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.RouterGatewayPortsByEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.RouterInterfacePortsByEndpoints;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.l3.endpoints.ExternalGatewayAsL3Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.l3.endpoints.ExternalGatewayAsL3EndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomainKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.floating.ip.ports.by.endpoints.FloatingIpPortByEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.floating.ip.ports.by.endpoints.FloatingIpPortByEndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpoint;
@@ -151,4 +155,13 @@ public class NeutronGbpIidFactory {
             .build();
     }
 
+    public static InstanceIdentifier<ExternalNetworkByL2FloodDomain> externalNetworkByL2FloodDomain(L2FloodDomainId l2FdId) {
+        return InstanceIdentifier.builder(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+                .child(NeutronByGbpMappings.class)
+                .child(ExternalNetworksByL2FloodDomains.class)
+                .child(ExternalNetworkByL2FloodDomain.class, new ExternalNetworkByL2FloodDomainKey(l2FdId))
+                .build();
+    }
+
 }
index 82d9e6e937a503e4262488616e728b58f6ae54f3..a84e7423fd6eeeb1ac68eaff4e69478a60e02e8d 100644 (file)
@@ -14,6 +14,7 @@ import java.util.UUID;
 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;
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
@@ -27,6 +28,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
@@ -111,9 +114,25 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
             .build();
         rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping, true);
 
+        if (network.getRouterExternal() != null
+                && network.getRouterExternal() == true) {
+            addExternalNetworkIfMissing(l2Fd.getId(), rwTx);
+        }
         DataStoreHelper.submitToDs(rwTx);
     }
 
+    private void addExternalNetworkIfMissing(L2FloodDomainId l2FdId, ReadWriteTransaction rwTx) {
+        InstanceIdentifier<ExternalNetworkByL2FloodDomain> iid = NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId);
+        Optional<ExternalNetworkByL2FloodDomain> externalPresent = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+                iid, rwTx);
+        if (!externalPresent.isPresent()) {
+            ExternalNetworkByL2FloodDomainBuilder builder = new ExternalNetworkByL2FloodDomainBuilder()
+                .setL2FloodDomainId(l2FdId);
+            rwTx.put(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId), builder.build(), true);
+        }
+    }
+
     private void addEpgExternalIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
         Optional<EndpointGroup> potentialEpgExternal = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
                 IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), rwTx);
index 60f113dec88912153fff0cee23efa9f8537ed02d..6d4db023c9533d594bd46a62dfc56db730a30576 100644 (file)
@@ -12,20 +12,28 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 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;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.neutron.spi.INeutronSubnetAware;
 import org.opendaylight.neutron.spi.NeutronSubnet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubnetBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,6 +71,19 @@ public class NeutronSubnetAware implements INeutronSubnetAware {
         Subnet subnet = createSubnet(neutronSubnet);
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetId), subnet, true);
         DataStoreHelper.submitToDs(rwTx);
+        rwTx = dataProvider.newReadWriteTransaction();
+
+        L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
+        ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
+
+        if (isExternalNetwork(subnet.getParent(), rwTx)) {
+            LOG.trace("neutronSubnetCreated - adding L3 Endpoint");
+            IpAddress defaultGateway = Utils.createIpAddress(neutronSubnet.getGatewayIP());
+            //Create L3Endpoint for defaultGateway and write to externalGateways to L3Endpoints in neutron-gbp datastore
+            NetworkDomainId containment = new NetworkDomainId(neutronSubnet.getID());
+            NeutronPortAware.addL3EndpointForExternalGateway(tenantId, fwCtx.getL3Context().getId(), defaultGateway, containment ,rwTx);
+            DataStoreHelper.submitToDs(rwTx);
+        }
     }
 
     private Subnet createSubnet(NeutronSubnet neutronSubnet) {
@@ -76,6 +97,19 @@ public class NeutronSubnetAware implements INeutronSubnetAware {
         return subnetBuilder.build();
     }
 
+
+    private boolean isExternalNetwork(ContextId context, ReadWriteTransaction rwTx) {
+        L2FloodDomainId l2FdId = new L2FloodDomainId(context.getValue());
+        LOG.trace("neutronSubnetCreated - Looking up L2FD: {}", l2FdId);
+        InstanceIdentifier<ExternalNetworkByL2FloodDomain> iid = NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId);
+        Optional<ExternalNetworkByL2FloodDomain> external = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
+                iid, rwTx);
+        if (external.isPresent()) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * @see org.opendaylight.neutron.spi.INeutronSubnetAware#canUpdateSubnet(org.opendaylight.neutron.spi.NeutronSubnet,
      *      org.opendaylight.neutron.spi.NeutronSubnet)
index 1e0db7a86c3120305343c687e9775b29f6da89c5..ef233be182162e891c96b2d7529ed8c89c23f4d7 100644 (file)
@@ -96,6 +96,16 @@ module neutron-gbp-mapper {
                     uses gbp-endpoint:l3-key;
                 }
             }
+
+            container external-networks-by-l2-flood-domains {
+                list external-network-by-l2-flood-domain {
+                    key l2-flood-domain-id;
+                    leaf l2-flood-domain-id {
+                        description "The L2 Flood Domain ID";
+                        type gbp-common:l2-flood-domain-id;
+                    }
+                }
+            }
         }
 
         container gbp-by-neutron-mappings {
@@ -155,4 +165,4 @@ module neutron-gbp-mapper {
         }
     }
 
-}
\ No newline at end of file
+}