+/*
+ * Copyright (c) 2015 Intel, 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.mapper.mapping;
import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.ArrayList;
import java.util.List;
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.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
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.domain_extension.l2_l3.util.L2L3IidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.PortUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SubnetUtils;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
-import org.opendaylight.neutron.spi.INeutronPortCRUD;
-import org.opendaylight.neutron.spi.INeutronRouterAware;
-import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
-import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
-import org.opendaylight.neutron.spi.NeutronPort;
-import org.opendaylight.neutron.spi.NeutronRouter;
-import org.opendaylight.neutron.spi.NeutronRouter_Interface;
-import org.opendaylight.neutron.spi.NeutronSecurityRule;
-import org.opendaylight.neutron.spi.NeutronSubnet;
-import org.opendaylight.neutron.spi.Neutron_IPs;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.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.endpoint.rev140421.EndpointService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder;
-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.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;
-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.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType;
+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.Subnet;
+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.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
+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.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.gateways.as.endpoints.ExternalGatewayAsEndpoint;
+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.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
+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.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
-public class NeutronRouterAware implements INeutronRouterAware {
+public class NeutronRouterAware implements NeutronAware<Router> {
private static final Logger LOG = LoggerFactory.getLogger(NeutronRouterAware.class);
- private static final NeutronRouterAware INSTANCE = new NeutronRouterAware();
- private static DataBroker dataProvider;
- private static EndpointService epService;
-
- private NeutronRouterAware() {
- if (NeutronRouterAware.INSTANCE != null) {
- throw new IllegalStateException("Already instantiated");
- }
- }
-
- public static NeutronRouterAware getInstance() {
- return NeutronRouterAware.INSTANCE;
- }
-
- public static void init(DataBroker dataProvider, EndpointService epService) {
- NeutronRouterAware.dataProvider = checkNotNull(dataProvider);
- NeutronRouterAware.epService = checkNotNull(epService);
+ public static final InstanceIdentifier<Router> ROUTER_WILDCARD_IID =
+ InstanceIdentifier.builder(Neutron.class).child(Routers.class).child(Router.class).build();
+ private final DataBroker dataProvider;
+ private final EndpointRegistrator epRegistrator;
+
+ public NeutronRouterAware(DataBroker dataProvider, EndpointRegistrator epRegistrator) {
+ this.dataProvider = checkNotNull(dataProvider);
+ this.epRegistrator = checkNotNull(epRegistrator);
}
@Override
- public int canCreateRouter(NeutronRouter router) {
- LOG.trace("canCreateRouter - {}", router);
- // nothing to consider
- return StatusCode.OK;
- }
-
- @Override
- public void neutronRouterCreated(NeutronRouter router) {
- LOG.trace("neutronRouterCreated - {}", router);
- // TODO Li msunal external gateway
+ public void onCreated(Router router, Neutron neutron) {
+ LOG.trace("created router - {}", router);
+
+ ContextId routerl3ContextId = new ContextId(router.getUuid().getValue());
+ TenantId tenantId = new TenantId(router.getTenantId().getValue());
+ InstanceIdentifier<ForwardingContext> routerL3CtxIid = L2L3IidFactory.l3ContextIid(tenantId, routerl3ContextId);
+ ForwardingContextBuilder fwdCtxBuilder = new ForwardingContextBuilder();
+ Name routerName = null;
+ if (!Strings.isNullOrEmpty(router.getName())) {
+ try {
+ routerName = new Name(router.getName());
+ fwdCtxBuilder.setName(routerName);
+ } catch (Exception e) {
+ LOG.info("Name '{}' of Neutron Subnet '{}' is ignored.", router.getName(),
+ router.getUuid().getValue());
+ LOG.debug("Name exception", e);
+ }
+ }
+ ForwardingContext routerl3Context = fwdCtxBuilder.setContextId(routerl3ContextId)
+ .setContextType(MappingUtils.L3_CONTEXT)
+ .build();
+ WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
+ wTx.put(LogicalDatastoreType.CONFIGURATION, routerL3CtxIid, routerl3Context, true);
+ createTenantL3Context(new L3ContextId(routerl3ContextId), tenantId, routerName, wTx);
+ DataStoreHelper.submitToDs(wTx);
}
- @Override
- public int canUpdateRouter(NeutronRouter delta, NeutronRouter original) {
- LOG.trace("canUpdateRouter - delta: {} original: {}", delta, original);
- // TODO Li msunal external gateway
- return StatusCode.OK;
+ @Deprecated
+ private void createTenantL3Context(L3ContextId l3ContextId, TenantId tenantId, Name name, WriteTransaction wTx) {
+ L3ContextBuilder l3ContextBuilder = new L3ContextBuilder();
+ if (name != null) {
+ l3ContextBuilder.setName(name);
+ }
+ L3Context l3Context = l3ContextBuilder.setId(l3ContextId).build();
+ wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context, true);
}
@Override
- public void neutronRouterUpdated(NeutronRouter router) {
- LOG.trace("neutronRouterUpdated - {}", router);
- if (router.getExternalGatewayInfo() == null || router.getExternalGatewayInfo().getExternalFixedIPs() == null) {
- LOG.trace("neutronRouterUpdated - not an external Gateway");
- return;
- }
-
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
- if (portInterface == null) {
- LOG.warn("Illegal state - No provider for {}", INeutronPortCRUD.class.getName());
- return;
- }
+ public void onUpdated(Router oldRouter, Router newRouter, Neutron oldNeutron, Neutron newNeutron) {
+ LOG.trace("updated router - OLD: {}\nNEW: {}", oldRouter, newRouter);
ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
- TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
- L3ContextId l3ContextIdFromRouterId = new L3ContextId(router.getID());
- InstanceIdentifier<L3Context> l3ContextIidForRouterId = IidFactory.l3ContextIid(tenantId,
- l3ContextIdFromRouterId);
- Optional<L3Context> potentialL3ContextForRouter = DataStoreHelper.readFromDs(
- LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, rwTx);
- L3Context l3Context = null;
- if (potentialL3ContextForRouter.isPresent()) {
- l3Context = potentialL3ContextForRouter.get();
- } else { // add L3 context if missing
- l3Context = createL3ContextFromRouter(router);
- rwTx.put(LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, l3Context);
- }
-
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
- if (subnetInterface == null) {
- LOG.warn("Illegal state - No provider for {}", INeutronSubnetCRUD.class.getName());
- return;
- }
- NeutronSubnet defaultSubnet = subnetInterface.getSubnet(router.getExternalGatewayInfo()
- .getExternalFixedIPs()
- .get(0)
- .getSubnetUUID());
- IpAddress defaultGateway = null;
- if (defaultSubnet != null) {
- defaultGateway = Utils.createIpAddress(defaultSubnet.getGatewayIP());
- //Create L3Endpoint for defaultGateway and write to externalGateways to L3Endpoints in neutron-gbp datastore
- NetworkDomainId containment = new NetworkDomainId(defaultSubnet.getID());
- NeutronPortAware.addL3EndpointForExternalGateway(tenantId, l3Context.getId(), defaultGateway, containment ,rwTx);
- }
- // Create L3Prefix Endpoints for all routes
- if (router.getRoutes().isEmpty()) {
- List<String> defaultRoute = ImmutableList.of("0.0.0.0/0");
- router.setRoutes(defaultRoute);
-
- }
- if (l3ContextIdFromRouterId != null) {
- for (String route : router.getRoutes()) {
- IpPrefix ipPrefix = Utils.createIpPrefix(route);
- boolean addedL3Prefix = NeutronPortAware.addL3PrefixEndpoint(l3ContextIdFromRouterId, ipPrefix,
- defaultGateway, tenantId, rwTx, epService);
- if (!addedL3Prefix) {
- LOG.warn("Could not add EndpointL3Prefix for Neutron route {} for router {}", route, router.getID());
- rwTx.cancel();
- return;
- }
- }
- }
- for (Neutron_IPs externalFixedIp : router.getExternalGatewayInfo().getExternalFixedIPs()) {
- NeutronPort routerPort = portInterface.getPort(router.getGatewayPortId());
- IpAddress ipAddress = Utils.createIpAddress(routerPort.getFixedIPs().get(0).getIpAddress());
- // External subnet associated with gateway port should use the gateway IP not router IP.
- NeutronSubnet neutronSubnet = subnetInterface.getSubnet(externalFixedIp.getSubnetUUID());
- ipAddress = Utils.createIpAddress(neutronSubnet.getGatewayIP());
- SubnetId subnetId = new SubnetId(externalFixedIp.getSubnetUUID());
- Subnet subnet = resolveSubnetWithVirtualRouterIp(tenantId, subnetId, ipAddress, rwTx);
- if (subnet == null) {
+ TenantId tenantId = new TenantId(newRouter.getTenantId().getValue());
+ ContextId routerL3CtxId = new ContextId(newRouter.getUuid().getValue());
+
+ if (newRouter.getGatewayPortId() != null && oldRouter.getGatewayPortId() == null) {
+ // external network is attached to router
+ Uuid gatewayPortId = newRouter.getGatewayPortId();
+ Optional<Port> potentialGwPort = PortUtils.findPort(gatewayPortId, newNeutron.getPorts());
+ if (!potentialGwPort.isPresent()) {
+ LOG.warn("Illegal state - router gateway port {} does not exist for router {}.",
+ gatewayPortId.getValue(), newRouter);
rwTx.cancel();
return;
}
- rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
- if (Strings.isNullOrEmpty(routerPort.getTenantID())) {
- routerPort.setTenantID(router.getTenantID());
+ Port gwPort = potentialGwPort.get();
+ List<FixedIps> fixedIpsFromGwPort = gwPort.getFixedIps();
+ if (fixedIpsFromGwPort == null || fixedIpsFromGwPort.isEmpty()) {
+ LOG.warn("Illegal state - router gateway port {} does not contain fixed IPs {}",
+ gatewayPortId.getValue(), gwPort);
+ rwTx.cancel();
+ return;
}
- // create security rules for router
- List<NeutronSecurityRule> routerSecRules = createRouterSecRules(routerPort, null, rwTx);
- if (routerSecRules == null) {
+
+ // router can have only one external network
+ FixedIps ipWithSubnetFromGwPort = fixedIpsFromGwPort.get(0);
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet> potentialSubnet = SubnetUtils.findSubnet(ipWithSubnetFromGwPort.getSubnetId(), newNeutron.getSubnets());
+ if (!potentialSubnet.isPresent()) {
+ LOG.warn("Illegal state - Subnet {} does not exist for router {}.",
+ ipWithSubnetFromGwPort.getSubnetId(), newRouter);
rwTx.cancel();
return;
}
- for (NeutronSecurityRule routerSecRule : routerSecRules) {
- boolean isRouterSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(routerSecRule, rwTx);
- if (!isRouterSecRuleAdded) {
- rwTx.cancel();
- return;
- }
+ IpPrefix gatewayIp = MappingUtils.ipAddressToIpPrefix(potentialSubnet.get().getGatewayIp());
+ boolean registeredExternalGateway = registerExternalGateway(tenantId, gatewayIp,
+ routerL3CtxId, new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId().getValue()));
+ if (!registeredExternalGateway) {
+ LOG.warn("Could not add L3Prefix as gateway of default route. Gateway port {}", gwPort);
+ rwTx.cancel();
+ return;
}
-
- boolean isSuccessful = setNewL3ContextToEpsFromSubnet(tenantId, l3Context, subnet, rwTx);
- if (!isSuccessful) {
+ addNeutronExtGwGbpMapping(routerL3CtxId, gatewayIp, rwTx);
+ NetworkDomain subnetDomain = createSubnetWithVirtualRouterIp(gatewayIp, new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId()
+ .getValue()));
+ rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()),
+ subnetDomain);
+ ContextId l2BdId = new ContextId(potentialSubnet.get().getNetworkId().getValue());
+ Optional<ForwardingContext> optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
+ if (!optBd.isPresent()) {
+ LOG.warn(
+ "Could not read L2-Bridge-Domain {}. Modification of its parent to L3-Context of router {} aborted.",
+ l2BdId, newRouter.getUuid());
rwTx.cancel();
return;
}
+ ForwardingContext l2BdWithGw = new ForwardingContextBuilder(optBd.get())
+ .setParent(MappingUtils.createParent(routerL3CtxId, MappingUtils.L3_CONTEXT))
+ .build();
+ rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId),
+ l2BdWithGw);
}
-
+ updateTenantForwarding(newNeutron, oldRouter, newRouter, new L3ContextId(routerL3CtxId), tenantId, rwTx);
DataStoreHelper.submitToDs(rwTx);
}
- @Override
- public int canDeleteRouter(NeutronRouter router) {
- LOG.trace("canDeleteRouter - {}", router);
- // nothing to consider
- return StatusCode.OK;
+ private boolean registerExternalGateway(TenantId tenantId, IpPrefix ipPrefix, ContextId routerl3ContextId,
+ NetworkDomainId networkDomainId) {
+ AddressEndpointRegBuilder addrEpBuilder = new AddressEndpointRegBuilder();
+ addrEpBuilder.setAddressType(IpPrefixType.class);
+ addrEpBuilder.setAddress(MappingUtils.ipPrefixToStringIpAddress(ipPrefix));
+ addrEpBuilder.setContextId(routerl3ContextId);
+ addrEpBuilder.setContextType(MappingUtils.L3_CONTEXT);
+ addrEpBuilder.setTenant(tenantId);
+ addrEpBuilder.setNetworkContainment(new NetworkContainmentBuilder().setContainment(
+ new NetworkDomainContainmentBuilder().setNetworkDomainId(networkDomainId).build()).build());
+ addrEpBuilder.setEndpointGroup(ImmutableList.of(MappingUtils.EPG_EXTERNAL_ID));
+ addrEpBuilder.setTimestamp(System.currentTimeMillis());
+ return epRegistrator.registerEndpoint(addrEpBuilder.build());
}
- @Override
- public void neutronRouterDeleted(NeutronRouter router) {
- LOG.trace("neutronRouterDeleted - {}", router);
- ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
- TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
- Optional<EndpointGroup> potentialEpg = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
- IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), rwTx);
- if (!potentialEpg.isPresent()) {
- LOG.warn("Illegal state - Endpoint group {} does not exist.", MappingUtils.EPG_ROUTER_ID.getValue());
- rwTx.cancel();
- return;
- }
- DataStoreHelper.submitToDs(rwTx);
+ private NetworkDomain createSubnetWithVirtualRouterIp(IpPrefix gatewayIp, NetworkDomainId subnetId) {
+ Subnet subnet = new SubnetBuilder().setVirtualRouterIp(MappingUtils.ipPrefixToIpAddress(gatewayIp.getValue())).build();
+ return new NetworkDomainBuilder().setKey(new NetworkDomainKey(subnetId, MappingUtils.SUBNET))
+ .addAugmentation(SubnetAugmentForwarding.class,
+ new SubnetAugmentForwardingBuilder().setSubnet(subnet).build())
+ .build();
}
- @Override
- public int canAttachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface) {
- LOG.trace("canAttachInterface - router: {} interface: {}", router, routerInterface);
- try (ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction()) {
- L3ContextId l3ContextIdFromRouterId = new L3ContextId(router.getID());
- TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
- SubnetId subnetId = new SubnetId(routerInterface.getSubnetUUID());
- Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
- IidFactory.subnetIid(tenantId, subnetId), rTx);
- if (!potentialSubnet.isPresent()) {
- LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
- return StatusCode.NOT_FOUND;
- }
- Subnet subnet = potentialSubnet.get();
- L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
- ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rTx);
- if (fwCtx.getL3Context() != null && fwCtx.getL3Context().getId().equals(l3ContextIdFromRouterId)) {
- // TODO Be msunal
- LOG.warn("Illegal state - Neutron mapper does not support multiple router interfaces in the same subnet yet.");
- return StatusCode.FORBIDDEN;
- }
- return StatusCode.OK;
- }
+ @Deprecated
+ private void updateTenantForwarding(Neutron newNeutron, Router oldRouter, Router newRouter, L3ContextId l3ContextId, TenantId tenantId, ReadWriteTransaction rwTx) {
+ InstanceIdentifier<L3Context> l3ContextIid =
+ IidFactory.l3ContextIid(tenantId, l3ContextId);
+ Optional<L3Context> optL3Context = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, l3ContextIid, rwTx);
+ L3Context l3Context = null;
+ if (optL3Context.isPresent()) {
+ l3Context = optL3Context.get();
+ } else { // add L3 context if missing
+ l3Context = createL3CtxFromRouter(newRouter);
+ rwTx.put(LogicalDatastoreType.CONFIGURATION, l3ContextIid, l3Context, true);
+ }
+
+ if (newRouter.getGatewayPortId() != null && oldRouter.getGatewayPortId() == null) {
+ // external network is attached to router
+ Uuid gatewayPortId = newRouter.getGatewayPortId();
+ Optional<Port> potentialGwPort = PortUtils.findPort(gatewayPortId, newNeutron.getPorts());
+ if (!potentialGwPort.isPresent()) {
+ LOG.warn("Illegal state - router gateway port {} does not exist for router {}.",
+ gatewayPortId.getValue(), newRouter);
+ rwTx.cancel();
+ return;
+ }
+
+ Port gwPort = potentialGwPort.get();
+ List<FixedIps> fixedIpsFromGwPort = gwPort.getFixedIps();
+ if (fixedIpsFromGwPort == null || fixedIpsFromGwPort.isEmpty()) {
+ LOG.warn("Illegal state - router gateway port {} does not contain fixed IPs {}",
+ gatewayPortId.getValue(), gwPort);
+ rwTx.cancel();
+ return;
+ }
+
+ // router can have only one external network
+ FixedIps ipWithSubnetFromGwPort = fixedIpsFromGwPort.get(0);
+ Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet> potentialSubnet = SubnetUtils.findSubnet(ipWithSubnetFromGwPort.getSubnetId(), newNeutron.getSubnets());
+ if (!potentialSubnet.isPresent()) {
+ LOG.warn("Illegal state - Subnet {} does not exist for router {}.",
+ ipWithSubnetFromGwPort.getSubnetId(), newRouter);
+ rwTx.cancel();
+ return;
+ }
+ IpAddress gatewayIp = potentialSubnet.get().getGatewayIp();
+ NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnetFromGwPort.getSubnetId().getValue());
+ boolean registeredExternalGateway = epRegistrator.registerL3EpAsExternalGateway(tenantId, gatewayIp,
+ l3ContextId, networkContainment);
+ if (!registeredExternalGateway) {
+ LOG.warn("Could not add L3Prefix as gateway of default route. Gateway port {}", gwPort);
+ rwTx.cancel();
+ return;
+ }
+ EndpointL3Key epL3Key = new EndpointL3Key(gatewayIp, l3ContextId);
+ addNeutronExtGwMapping(epL3Key, rwTx);
+
+ boolean registeredDefaultRoute = epRegistrator.registerExternalL3PrefixEndpoint(MappingUtils.DEFAULT_ROUTE,
+ l3ContextId, gatewayIp, tenantId);
+ if (!registeredDefaultRoute) {
+ LOG.warn("Could not add EndpointL3Prefix as default route. Gateway port {}", gwPort);
+ rwTx.cancel();
+ return;
+ }
+ org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet subnetWithGw =
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.SubnetBuilder().setId(new SubnetId(ipWithSubnetFromGwPort.getSubnetId().getValue()))
+ .setVirtualRouterIp(gatewayIp)
+ .build();
+ rwTx.merge(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetWithGw.getId()),
+ subnetWithGw);
+ L2BridgeDomainId l2BdId = new L2BridgeDomainId(potentialSubnet.get().getNetworkId().getValue());
+ Optional<L2BridgeDomain> optBd = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
+ IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
+ if (!optBd.isPresent()) {
+ LOG.warn(
+ "Could not read L2-Bridge-Domain {}. Modification of its parent to L3-Context of router {} aborted.",
+ l2BdId, newRouter.getUuid());
+ rwTx.cancel();
+ return;
+ }
+ L2BridgeDomain l2BdWithGw = new L2BridgeDomainBuilder(optBd.get())
+ .setParent(new L3ContextId(l3ContextId.getValue()))
+ .build();
+ rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId),
+ l2BdWithGw);
+ }
}
- @Override
- public void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface) {
- LOG.trace("neutronRouterInterfaceAttached - router: {} interface: {}", router, routerInterface);
- INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
- if (portInterface == null) {
- LOG.warn("Illegal state - No provider for {}", INeutronPortCRUD.class.getName());
- return;
- }
-
- ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
- TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
- L3ContextId l3ContextIdFromRouterId = new L3ContextId(router.getID());
- InstanceIdentifier<L3Context> l3ContextIidForRouterId = IidFactory.l3ContextIid(tenantId,
- l3ContextIdFromRouterId);
- Optional<L3Context> potentialL3ContextForRouter = DataStoreHelper.readFromDs(
- LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, rwTx);
- L3Context l3Context = null;
- if (potentialL3ContextForRouter.isPresent()) {
- l3Context = potentialL3ContextForRouter.get();
- } else { // add L3 context if missing
- l3Context = createL3ContextFromRouter(router);
- rwTx.put(LogicalDatastoreType.CONFIGURATION, l3ContextIidForRouterId, l3Context);
- }
-
- // Based on Neutron Northbound - Port representing router interface
- // contains exactly on fixed IP
- NeutronPort routerPort = portInterface.getPort(routerInterface.getPortUUID());
- SubnetId subnetId = new SubnetId(routerInterface.getSubnetUUID());
- IpAddress ipAddress = Utils.createIpAddress(routerPort.getFixedIPs().get(0).getIpAddress());
- Subnet subnet = resolveSubnetWithVirtualRouterIp(tenantId, subnetId, ipAddress, rwTx);
- if (subnet == null) {
- rwTx.cancel();
- return;
- }
- rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnet.getId()), subnet);
-
- // create security rules for router
- List<NeutronSecurityRule> routerSecRules = createRouterSecRules(routerPort, null, rwTx);
- if (routerSecRules == null) {
- rwTx.cancel();
- return;
- }
- for (NeutronSecurityRule routerSecRule : routerSecRules) {
- boolean isRouterSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(routerSecRule, rwTx);
- if (!isRouterSecRuleAdded) {
- rwTx.cancel();
- return;
- }
- }
-
- boolean isSuccessful = setNewL3ContextToEpsFromSubnet(tenantId, l3Context, subnet, rwTx);
- if (!isSuccessful) {
- rwTx.cancel();
- return;
+ private static @Nonnull ForwardingContext createL3ContextFromRouter(
+ Router router) {
+ Name l3ContextName = null;
+ if (!Strings.isNullOrEmpty(router.getName())) {
+ l3ContextName = new Name(router.getName());
}
-
- DataStoreHelper.submitToDs(rwTx);
+ return new ForwardingContextBuilder().setContextId(new ContextId(router.getUuid().getValue()))
+ .setContextType(MappingUtils.L3_CONTEXT)
+ .setName(new Name(l3ContextName.getValue()))
+ .build();
}
- private static @Nonnull L3Context createL3ContextFromRouter(NeutronRouter router) {
+ @Deprecated
+ private static @Nonnull L3Context createL3CtxFromRouter(Router router) {
Name l3ContextName = null;
if (!Strings.isNullOrEmpty(router.getName())) {
l3ContextName = new Name(router.getName());
}
- return new L3ContextBuilder().setId(new L3ContextId(router.getID()))
+ return new L3ContextBuilder().setId(new L3ContextId(router.getUuid().getValue()))
.setName(l3ContextName)
- .setDescription(new Description(MappingUtils.NEUTRON_ROUTER__ + router.getID()))
+ .setDescription(new Description(MappingUtils.NEUTRON_ROUTER + router.getUuid().getValue()))
.build();
}
- private @Nullable Subnet resolveSubnetWithVirtualRouterIp(TenantId tenantId, SubnetId subnetId,
- IpAddress ipAddress, ReadTransaction rTx) {
- Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
- IidFactory.subnetIid(tenantId, subnetId), rTx);
- if (!potentialSubnet.isPresent()) {
- LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
- return null;
- }
-
- // TODO: Li alagalah: Add gateways and prefixes instead of
- // VirtualRouterID
- return new SubnetBuilder(potentialSubnet.get()).setVirtualRouterIp(ipAddress).build();
- }
-
- /**
- * @return {@code false} if illegal state occurred; {@code true} otherwise
- */
- public boolean setNewL3ContextToEpsFromSubnet(TenantId tenantId, L3Context l3Context, Subnet subnet,
- ReadWriteTransaction rwTx) {
- if (subnet.getParent() == null) {
- LOG.warn("Illegal state - subnet {} does not have a parent.", subnet.getId().getValue());
- return false;
- }
-
- L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
- ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
- if (fwCtx.getL2BridgeDomain() == null) {
- LOG.warn("Illegal state - l2-flood-domain {} does not have a parent.", l2FdId.getValue());
- return false;
- }
-
- L2BridgeDomain l2BridgeDomain = new L2BridgeDomainBuilder(fwCtx.getL2BridgeDomain()).setParent(
- l3Context.getId()).build();
- rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BridgeDomain.getId()),
- l2BridgeDomain);
-
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
- if (subnetInterface == null) {
- LOG.warn("Illegal state - No provider for {}", INeutronSubnetCRUD.class.getName());
- return false;
- }
-
- List<L3> l3Eps = new ArrayList<>();
- L3ContextId oldL3ContextId = fwCtx.getL3Context().getId();
- NeutronSubnet neutronSubnet = subnetInterface.getSubnet(subnet.getId().getValue());
- List<NeutronPort> portsInNeutronSubnet = neutronSubnet.getPortsInSubnet();
- for (NeutronPort port : portsInNeutronSubnet) {
- boolean isPortAdded = NeutronPortAware.addNeutronPort(port, rwTx, epService);
- if (!isPortAdded) {
- return false;
- }
- // TODO Li msunal this has to be rewrite when OFOverlay renderer
- // will support l3-endpoints.
- Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
- if (firstIp != null) {
- l3Eps.add(new L3Builder().setL3Context(oldL3ContextId)
- .setIpAddress(Utils.createIpAddress(firstIp.getIpAddress()))
- .build());
- }
- }
- if (neutronSubnet.getGatewayIP() != null) {
- l3Eps.add(new L3Builder().setL3Context(oldL3ContextId)
- .setIpAddress(Utils.createIpAddress(neutronSubnet.getGatewayIP()))
- .build());
- }
-
- if (!l3Eps.isEmpty()) {
- epService.unregisterEndpoint(new UnregisterEndpointInputBuilder().setL3(l3Eps).build());
- }
- return true;
- }
-
- public static List<NeutronSecurityRule> createRouterSecRules(NeutronPort port, EndpointGroupId consumerEpgId,
- ReadTransaction rTx) {
- TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
- Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs());
- if (firstIp == null) {
- LOG.warn("Illegal state - Router port does not have an IP address.");
- return null;
- }
- SubnetId routerSubnetId = new SubnetId(firstIp.getSubnetUUID());
- Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
- IidFactory.subnetIid(tenantId, routerSubnetId), rTx);
- if (!potentialSubnet.isPresent()) {
- LOG.warn("Illegal state - Subnet {} where is router port does not exist.", routerSubnetId.getValue());
- return null;
- }
- IpPrefix ipSubnet = potentialSubnet.get().getIpPrefix();
- NeutronSecurityRule routerRuleEgress = createRouterSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId,
- true);
- NeutronSecurityRule routerRuleIngress = createRouterSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId,
- false);
- return ImmutableList.of(routerRuleEgress, routerRuleIngress);
- }
-
- private static NeutronSecurityRule createRouterSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet,
- EndpointGroupId consumerEpgId, boolean isEgress) {
- NeutronSecurityRule routerSecRule = new NeutronSecurityRule();
- routerSecRule.setSecurityRuleGroupID(MappingUtils.EPG_ROUTER_ID.getValue());
- routerSecRule.setSecurityRuleTenantID(tenantId.getValue());
- routerSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
- if (isEgress) {
- routerSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "__" + ruleUuid);
- routerSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
- } else {
- routerSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "__" + ruleUuid);
- routerSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
- }
- if (ipSubnet.getIpv4Prefix() != null) {
- routerSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
- } else {
- routerSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
- }
- return routerSecRule;
+ private static void addNeutronExtGwGbpMapping(ContextId contextId, IpPrefix ipPrefix, ReadWriteTransaction rwTx) {
+ ExternalGatewayAsEndpoint externalGatewayL3Endpoint = MappingFactory.createEaxternalGatewayAsEndpoint(
+ contextId, ipPrefix);
+ rwTx.put(LogicalDatastoreType.OPERATIONAL,
+ NeutronGbpIidFactory.externalGatewayAsEndpoint(contextId, ipPrefix, MappingUtils.L3_CONTEXT), externalGatewayL3Endpoint, true);
}
- @Override
- public int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface) {
- LOG.trace("canDetachInterface - router: {} interface: {}", router, routerInterface);
- // nothing to consider
- return StatusCode.OK;
+ @Deprecated
+ private static void addNeutronExtGwMapping(EndpointL3Key epL3Key, ReadWriteTransaction rwTx) {
+ ExternalGatewayAsL3Endpoint externalGatewayL3Endpoint =
+ MappingFactory.createExternalGatewayByL3Endpoint(epL3Key);
+ rwTx.put(LogicalDatastoreType.OPERATIONAL,
+ NeutronGbpIidFactory.externalGatewayAsL3Endpoint(epL3Key.getL3Context(), epL3Key.getIpAddress()),
+ externalGatewayL3Endpoint, true);
}
@Override
- public void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface) {
- LOG.trace("neutronRouterInterfaceDetached - router: {} interface: {}", router, routerInterface);
- INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
- if (subnetInterface == null) {
- LOG.warn("Illegal state - No provider for {}", INeutronSubnetCRUD.class.getName());
- return;
- }
-
- ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
- TenantId tenantId = new TenantId(Utils.normalizeUuid(router.getTenantID()));
- L3ContextId l3ContextId = new L3ContextId(router.getID());
- SubnetId subnetId = new SubnetId(routerInterface.getSubnetUUID());
- InstanceIdentifier<L3Context> l3ContextIid = IidFactory.l3ContextIid(tenantId, l3ContextId);
- DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
- IidFactory.l3ContextIid(tenantId, l3ContextId), rwTx);
-
- Optional<Subnet> potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
- IidFactory.subnetIid(tenantId, subnetId), rwTx);
- if (!potentialSubnet.isPresent()) {
- LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
- rwTx.cancel();
- return;
- }
-
- Subnet subnet = new SubnetBuilder(potentialSubnet.get()).setVirtualRouterIp(null).build();
- rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetId), subnet);
-
- L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
- ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
- if (fwCtx.getL2BridgeDomain() == null) {
- LOG.warn("Illegal state - l2-flood-domain {} does not have a parent.", l2FdId.getValue());
- rwTx.cancel();
- return;
- }
-
- Optional<NetworkMapping> potentialNetworkMapping = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
- NeutronMapperIidFactory.networkMappingIid(l2FdId), rwTx);
- if (!potentialNetworkMapping.isPresent()) {
- LOG.warn("Illegal state - network-mapping {} does not exist.", l2FdId.getValue());
- rwTx.cancel();
- return;
- }
-
- L2BridgeDomain l2BridgeDomain = new L2BridgeDomainBuilder(fwCtx.getL2BridgeDomain()).setParent(
- potentialNetworkMapping.get().getL3ContextId()).build();
- rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BridgeDomain.getId()),
- l2BridgeDomain);
-
- NeutronSubnet neutronSubnet = subnetInterface.getSubnet(subnetId.getValue());
- List<NeutronPort> portsInNeutronSubnet = neutronSubnet.getPortsInSubnet();
- for (NeutronPort port : portsInNeutronSubnet) {
- boolean isPortAdded = NeutronPortAware.addNeutronPort(port, rwTx, epService);
- if (!isPortAdded) {
- rwTx.cancel();
- return;
- }
- }
+ public void onDeleted(Router router, Neutron oldNeutron, Neutron newNeutron) {
+ LOG.trace("deleted router - {}", router);
}
}