From: Vladimir Lavor Date: Fri, 13 Jan 2017 13:58:56 +0000 (+0100) Subject: Neutron port removal fixed X-Git-Tag: release/carbon~49^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=groupbasedpolicy.git;a=commitdiff_plain;h=81de018f6fd0dd13818e636b7ea577eec3ed536d Neutron port removal fixed * L3 context update is applied only for persistent ports within subnet to avoid recreation of previously removed ones * Router interface port is now already removed in onDelete * vif-type is considered if port update Change-Id: I4d1331845e19313f50a563206f6c4efe67e1fca6 Signed-off-by: Vladimir Lavor --- diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java index 8bdfa6bf3..e1e7a4b7b 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/EndpointRegistrator.java @@ -8,12 +8,12 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; - -import javax.annotation.Nullable; - +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; 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; @@ -22,15 +22,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInputBuilder; -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.AddressEndpointReg; -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.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnreg; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.unregister.endpoint.input.AddressEndpointUnregBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; @@ -40,14 +34,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3AddressBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3Gateways; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.l3.prefix.fields.EndpointL3GatewaysBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; - public class EndpointRegistrator { private static final Logger LOG = LoggerFactory.getLogger(EndpointRegistrator.class); diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java index ac008035c..f5f1939b3 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java @@ -7,12 +7,12 @@ */ package org.opendaylight.groupbasedpolicy.neutron.mapper; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener; @@ -67,7 +67,7 @@ import com.google.common.collect.PeekingIterator; public class NeutronMapper implements ClusteredDataTreeChangeListener, AutoCloseable { - public static final String EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA = "Unknown modification type within data "; + private static final String EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA = "Unknown modification type within data "; private final static SecurityRuleBuilder EIG_INGRESS_IPV4_SEC_RULE_BUILDER = new SecurityRuleBuilder() .setUuid(new Uuid("0a629f80-2408-11e6-b67b-9e71128cae77")) @@ -120,7 +120,7 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener, } @Override - public void onDataTreeChanged(Collection> changes) { + public void onDataTreeChanged(@Nonnull Collection> changes) { for (DataTreeModification change : changes) { DataObjectModification neutronModif = change.getRootNode(); resolveAndSetNeutron(neutronModif); @@ -164,24 +164,19 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener, private void onDataObjectModification(List> dataModifs, NeutronAware neutronAware) { for (DataObjectModification dataModif : dataModifs) { - switch (dataModif.getModificationType()) { - case DELETE: - neutronAware.onDeleted(dataModif.getDataBefore(), neutronBefore, neutronAfter); - break; - case SUBTREE_MODIFIED: - neutronAware.onUpdated(dataModif.getDataBefore(), dataModif.getDataAfter(), neutronBefore, - neutronAfter); - break; - case WRITE: - if (dataModif.getDataBefore() == null) { - neutronAware.onCreated(dataModif.getDataAfter(), neutronAfter); - } else { - neutronAware.onUpdated(dataModif.getDataBefore(), dataModif.getDataAfter(), neutronBefore, - neutronAfter); - } - break; - default: - throw new IllegalStateException(EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA + dataModif); + final T dataBefore = dataModif.getDataBefore(); + final T dataAfter = dataModif.getDataAfter(); + if (dataBefore == null && dataAfter != null) { + neutronAware.onCreated(dataAfter, neutronAfter); + } + else if (dataBefore != null && dataAfter != null) { + neutronAware.onUpdated(dataBefore, dataAfter, neutronBefore, neutronAfter); + } + else if (dataBefore != null) { + neutronAware.onDeleted(dataBefore, neutronBefore, neutronAfter); + } + else { + throw new IllegalStateException(EXC_MSG_UNKNOWN_MODIFICATION_TYPE_WITHIN_DATA + dataModif); } } } diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java index e240de078..07a0129a8 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java @@ -15,6 +15,7 @@ import java.util.Set; import javax.annotation.Nullable; +import com.sun.jndi.cosnaming.IiopUrl; 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; @@ -544,15 +545,15 @@ public class NeutronPortAware implements NeutronAware { @Override public void onUpdated(Port oldPort, Port newPort, Neutron oldNeutron, Neutron newNeutron) { LOG.trace("updated port - OLD: {}\nNEW: {}", oldPort, newPort); - onDeleted(oldPort, oldNeutron, false); + onDeleted(oldPort, oldNeutron, newNeutron, false); onCreated(newPort, newNeutron, false); } @Override public void onDeleted(Port deletedItem, Neutron oldNeutron, Neutron newNeutron) { - onDeleted(deletedItem, oldNeutron, true); + onDeleted(deletedItem, oldNeutron, newNeutron, true); } - public void onDeleted(Port port, Neutron oldNeutron, boolean removeBaseEpMapping) { + public void onDeleted(Port port, Neutron oldNeutron, Neutron newNeutron, boolean removeBaseEpMapping) { LOG.trace("deleted port - {}", port); if (PortUtils.isRouterInterfacePort(port)) { LOG.trace("Port is router interface port: {}", port.getUuid().getValue()); @@ -566,7 +567,7 @@ public class NeutronPortAware implements NeutronAware { FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get(); L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue()); // change L3Context for all EPs with same subnet as router port - changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), oldNeutron); + changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), newNeutron); // set L3Context as parent for bridge domain which is parent of subnet TenantId tenantId = new TenantId(port.getTenantId().getValue()); Optional potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), @@ -588,12 +589,8 @@ public class NeutronPortAware implements NeutronAware { NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null); rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()), subnet); - UniqueId portId = new UniqueId(port.getUuid().getValue()); - PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress().getValue(), - MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN); - if (removeBaseEpMapping) { - removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx); - } + unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx); + unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping); DataStoreHelper.submitToDs(rwTx); } else if (PortUtils.isDhcpPort(port)) { LOG.trace("Port is DHCP port: {}", port.getUuid().getValue()); diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java index 3c25a8c91..32fe340a7 100644 --- a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java +++ b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java @@ -66,13 +66,14 @@ import com.google.common.base.Optional; public class PortHandler implements TransactionChainListener { - private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(PortHandler.class); private static final String COMPUTE_OWNER = "compute"; private static final String DHCP_OWNER = "dhcp"; private static final String ROUTER_OWNER = "network:router_interface"; private static final String[] SUPPORTED_DEVICE_OWNERS = {COMPUTE_OWNER, DHCP_OWNER, ROUTER_OWNER}; private static final String VHOST_USER = "vhostuser"; + private static final String UNBOUND = "unbound"; private static final String VPP_INTERFACE_NAME_PREFIX = "neutron_port_"; private static final String TAP_PORT_NAME_PREFIX = "tap"; private static final String RT_PORT_NAME_PREFIX = "qr-"; @@ -158,18 +159,38 @@ public class PortHandler implements TransactionChainListener { processCreated(delta); } - private boolean isUpdateNeeded(Port oldPort, Port newPort) { + private boolean isUpdateNeeded(final Port oldPort, final Port newPort) { //TODO fix this to better support update of ports for VPP - PortBindingExtension oldPortAugmentation = oldPort.getAugmentation(PortBindingExtension.class); - PortBindingExtension newPortAugmentation = newPort.getAugmentation(PortBindingExtension.class); - - List vifDetails = oldPortAugmentation.getVifDetails(); + final PortBindingExtension oldPortAugmentation = oldPort.getAugmentation(PortBindingExtension.class); + final PortBindingExtension newPortAugmentation = newPort.getAugmentation(PortBindingExtension.class); if (newPortAugmentation == null) { LOG.trace("Port {} is no longer a vhost type port, updating port..."); return true; } + final String oldDeviceOwner = oldPort.getDeviceOwner(); + final String oldVifType = oldPortAugmentation.getVifType(); + final String newDeviceOwner = newPort.getDeviceOwner(); + final String newVifType = newPortAugmentation.getVifType(); + + // TODO potential bug here + // Temporary change for Openstack Mitaka: If old neutron-binding:vif-type is vhost, new one is unbound and + // device owner is ROUTER_OWNER, skip update. Openstack (or ml2) sometimes sends router update messages in + // incorrect order which causes unwanted port removal + if (oldVifType.equals(VHOST_USER) && newVifType.equals(UNBOUND) && oldDeviceOwner != null && + ROUTER_OWNER.equals(oldDeviceOwner) && ROUTER_OWNER.equals(newDeviceOwner)) { + LOG.warn("Port vif-type was updated from vhost to unbound. This update is currently disabled and will be skipped"); + return false; + } + + if (newVifType != null && !newVifType.equals(oldVifType)) { + LOG.trace("Vif type changed, old: {} new {}", oldVifType, newVifType); + return true; + } + + final List vifDetails = oldPortAugmentation.getVifDetails(); + if (!oldPortAugmentation.getHostId().equals(newPortAugmentation.getHostId()) || nullToEmpty(vifDetails).size() != nullToEmpty(newPortAugmentation.getVifDetails()).size()) { return true;