segmentation-id is stored to DS if a neutron network is backed by physical network
Change-Id: Id7334fc0a088a32879396ce7f2e48cdb06d250dc
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
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.TenantId;
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.GbpByNeutronMappings;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.NeutronByGbpMappings;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.ports.EndpointByPortKey;
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.PortsByEndpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ProviderPhysicalNetworksAsL2FloodDomains;
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.ports.by.endpoints.PortByEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
public class NeutronGbpIidFactory {
public static InstanceIdentifier<EndpointByPort> endpointByPortIid(UniqueId portId) {
- return InstanceIdentifier.builder(
- org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+ return InstanceIdentifier
+ .builder(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
.child(GbpByNeutronMappings.class)
.child(EndpointsByPorts.class)
.child(EndpointByPort.class, new EndpointByPortKey(portId))
}
public static InstanceIdentifier<PortByEndpoint> portByEndpointIid(L2BridgeDomainId l2BdId, MacAddress mac) {
- return InstanceIdentifier.builder(
- org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+ return InstanceIdentifier
+ .builder(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
.child(NeutronByGbpMappings.class)
.child(PortsByEndpoints.class)
.child(PortByEndpoint.class, new PortByEndpointKey(l2BdId, mac))
public static InstanceIdentifier<ExternalGatewayAsL3Endpoint> externalGatewayAsL3Endpoint(L3ContextId l3Context,
IpAddress ipAddress) {
- return InstanceIdentifier.builder(
- org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+ return InstanceIdentifier
+ .builder(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
.child(NeutronByGbpMappings.class)
.child(ExternalGatewaysAsL3Endpoints.class)
.child(ExternalGatewayAsL3Endpoint.class, new ExternalGatewayAsL3EndpointKey(ipAddress, l3Context))
.build();
}
+ public static InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> providerPhysicalNetworkAsL2FloodDomainIid(
+ TenantId tenantId, L2FloodDomainId l2FdId) {
+ return InstanceIdentifier
+ .builder(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings.class)
+ .child(NeutronByGbpMappings.class)
+ .child(ProviderPhysicalNetworksAsL2FloodDomains.class)
+ .child(ProviderPhysicalNetworkAsL2FloodDomain.class,
+ new ProviderPhysicalNetworkAsL2FloodDomainKey(l2FdId, tenantId))
+ .build();
+ }
+
}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.NeutronSecurityGroupAware;
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.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder;
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.forwarding.context.L2BridgeDomain;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
public class NeutronNetworkAware implements INeutronNetworkAware {
if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
addEigEpgExternalWithContracts(tenantId, rwTx);
}
+ if (!Strings.isNullOrEmpty(network.getProviderPhysicalNetwork())) {
+ String segmentationId = network.getProviderSegmentationID();
+ addProviderPhysicalNetworkMapping(tenantId, l2FdId, segmentationId, rwTx);
+ }
DataStoreHelper.submitToDs(rwTx);
}
IidFactory.externalImplicitGroupIid(tenantId, eig.getId()), eig, true);
}
+ private void addProviderPhysicalNetworkMapping(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId,
+ WriteTransaction wTx) {
+ ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new ProviderPhysicalNetworkAsL2FloodDomainBuilder()
+ .setTenantId(tenantId).setL2FloodDomainId(l2FdId).setSegmentationId(segmentationId).build();
+ wTx.put(LogicalDatastoreType.OPERATIONAL,
+ NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, l2FdId), provNetAsL2Fd);
+ }
+
/**
* @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
* org.opendaylight.neutron.spi.NeutronNetwork)
uses gbp-endpoint:l3-key;
}
}
+
+ container provider-physical-networks-as-l2-flood-domains {
+ list provider-physical-network-as-l2-flood-domain {
+ key "tenant-id l2-flood-domain-id";
+ leaf tenant-id {
+ description "Tenant of L2 Flood Domain";
+ type gbp-common:tenant-id;
+ }
+ leaf l2-flood-domain-id {
+ description "The L2 Flood Domain ID";
+ type gbp-common:l2-flood-domain-id;
+ }
+ leaf segmentation-id {
+ mandatory true;
+ description "An isolated segment on the physical network. The network-type
+ attribute defines the segmentation model. For example, if network-type
+ is vlan, this ID is a vlan identifier.";
+ type string;
+ }
+ }
+ }
}
container gbp-by-neutron-mappings {
public class NeutronOvsdb implements AutoCloseable {
private final TerminationPointDataChangeListener tpListener;
-// private final NodeDataChangeListener nodeListener;
private final PortByEndpointListener portByEndpointListener;
private final OvsdbNodeListener ovsdbNodeListener;
+ private final ProviderPhysicalNetworkListener provPhysNetListener;
public NeutronOvsdb(DataBroker dataProvider, RpcProviderRegistry rpcProvider) {
checkNotNull(dataProvider);
EndpointService epService = rpcProvider.getRpcService(EndpointService.class);
tpListener = new TerminationPointDataChangeListener(dataProvider, epService);
-// nodeListener = new NodeDataChangeListener(dataProvider);
ovsdbNodeListener = new OvsdbNodeListener(dataProvider);
portByEndpointListener = new PortByEndpointListener(dataProvider);
+ provPhysNetListener = new ProviderPhysicalNetworkListener(dataProvider);
}
/**
@Override
public void close() throws Exception {
tpListener.close();
-// nodeListener.close();
ovsdbNodeListener.close();
portByEndpointListener.close();
+ provPhysNetListener.close();
}
}
--- /dev/null
+/*
+ * 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.neutron.ovsdb;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+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.neutron.gbp.mapper.rev150513.Mappings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.NeutronByGbpMappings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ProviderPhysicalNetworksAsL2FloodDomains;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
+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.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
+public class ProviderPhysicalNetworkListener extends DataTreeChangeHandler<ProviderPhysicalNetworkAsL2FloodDomain> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ProviderPhysicalNetworkListener.class);
+
+ protected ProviderPhysicalNetworkListener(DataBroker dataProvider) {
+ super(dataProvider,
+ new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(Mappings.class)
+ .child(NeutronByGbpMappings.class)
+ .child(ProviderPhysicalNetworksAsL2FloodDomains.class)
+ .child(ProviderPhysicalNetworkAsL2FloodDomain.class)
+ .build()));
+ }
+
+ @Override
+ protected void onWrite(DataObjectModification<ProviderPhysicalNetworkAsL2FloodDomain> rootNode,
+ InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> rootIdentifier) {
+ L2FloodDomainId l2FdId = rootNode.getDataAfter().getL2FloodDomainId();
+ TenantId tenantId = rootNode.getDataAfter().getTenantId();
+ String segmentationId = rootNode.getDataAfter().getSegmentationId();
+ augmentSegmentationToFloodDomain(tenantId, l2FdId, segmentationId);
+ }
+
+ @Override
+ protected void onDelete(DataObjectModification<ProviderPhysicalNetworkAsL2FloodDomain> rootNode,
+ InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> rootIdentifier) {
+ L2FloodDomainId l2FdId = rootNode.getDataBefore().getL2FloodDomainId();
+ TenantId tenantId = rootNode.getDataBefore().getTenantId();
+ augmentSegmentationToFloodDomain(tenantId, l2FdId, null);
+ }
+
+ @Override
+ protected void onSubtreeModified(DataObjectModification<ProviderPhysicalNetworkAsL2FloodDomain> rootNode,
+ InstanceIdentifier<ProviderPhysicalNetworkAsL2FloodDomain> rootIdentifier) {
+ L2FloodDomainId l2FdId = rootNode.getDataAfter().getL2FloodDomainId();
+ TenantId tenantId = rootNode.getDataAfter().getTenantId();
+ String segmentationId = rootNode.getDataAfter().getSegmentationId();
+ augmentSegmentationToFloodDomain(tenantId, l2FdId, segmentationId);
+ }
+
+ private void augmentSegmentationToFloodDomain(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId) {
+ if (Strings.isNullOrEmpty(segmentationId)) {
+ ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+ DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
+ IidFactory.l2FloodDomainIid(tenantId, l2FdId).augmentation(Segmentation.class), rwTx);
+ DataStoreHelper.submitToDs(rwTx);
+ } else {
+ try {
+ Segmentation segmentation =
+ new SegmentationBuilder().setSegmentationId(Integer.valueOf(segmentationId)).build();
+ WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+ wTx.merge(LogicalDatastoreType.CONFIGURATION,
+ IidFactory.l2FloodDomainIid(tenantId, l2FdId).augmentation(Segmentation.class), segmentation);
+ DataStoreHelper.submitToDs(wTx);
+ } catch (NumberFormatException e) {
+ LOG.info("Segmentation ID of Neutron Provider Physical Network {} is not a number but is {}.",
+ l2FdId.getValue(), segmentationId);
+ }
+ }
+ }
+
+}