Added new FlowTables (NATMapper, ExternalMapper)
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronPortAware.java
index e40e71a4dea4ada1211b9a8d08d707448a28bfa5..04b5d49a2da8898ae74f8fe25beb0ff8ea618d11 100644 (file)
@@ -11,8 +11,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 
@@ -21,12 +23,13 @@ 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.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.DataStoreHelper;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.IidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.neutron.spi.INeutronPortAware;
 import org.opendaylight.neutron.spi.NeutronPort;
 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
@@ -39,6 +42,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev
 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.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.common.rev140421.UniqueId;
@@ -56,15 +60,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2Builder;
 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.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.floating.ip.ports.EndpointByFloatingIpPort;
 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.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.gbp.by.neutron.mappings.endpoints.by.router._interface.ports.EndpointByRouterInterfacePort;
 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.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.floating.ip.ports.by.endpoints.FloatingIpPortByEndpoint;
 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.router._interface.ports.by.endpoints.RouterInterfacePortByEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.router.gateway.ports.by.endpoints.RouterGatewayPortByEndpoint;
@@ -73,6 +81,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextInputBuilder;
 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.Subnet;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -90,10 +99,11 @@ public class NeutronPortAware implements INeutronPortAware {
     private static final String DEVICE_OWNER_ROUTER_IFACE = "network:router_interface";
     private static final String DEVICE_OWNER_ROUTER_GATEWAY = "network:router_gateway";
     private static final String DEVICE_OWNER_FLOATING_IP = "network:floatingip";
-    private static final int DHCP_CLIENT_PORT = 68;
     private static final int DHCP_SERVER_PORT = 67;
+    private static final int DNS_SERVER_PORT = 53;
     private final DataBroker dataProvider;
     private final EndpointService epService;
+    private final static Map<String, UniqueId> floatingIpPortByDeviceId = new HashMap<>();
 
     public NeutronPortAware(DataBroker dataProvider, EndpointService epService) {
         this.dataProvider = checkNotNull(dataProvider);
@@ -131,8 +141,9 @@ public class NeutronPortAware implements INeutronPortAware {
                     NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
             return;
         }
-        if (isFloatingIp(port)) {
-            LOG.trace("Port is floating ip - {}", port.getID());
+        if (isFloatingIpPort(port)) {
+            LOG.trace("Port is floating ip - {} device id - {}", port.getID(), port.getDeviceID());
+            floatingIpPortByDeviceId.put(port.getDeviceID(), new UniqueId(port.getID()));
             return;
         }
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
@@ -210,51 +221,78 @@ public class NeutronPortAware implements INeutronPortAware {
 
         try {
             RegisterEndpointInput registerEpRpcInput = createRegisterEndpointInput(port, fwCtx);
-
             RpcResult<Void> rpcResult = epService.registerEndpoint(registerEpRpcInput).get();
             if (!rpcResult.isSuccessful()) {
                 LOG.warn("Illegal state - RPC registerEndpoint failed. Input of RPC: {}", registerEpRpcInput);
                 return false;
             }
         } catch (InterruptedException | ExecutionException e) {
-            LOG.error("addPort - RPC invocation failed.", e);
+            LOG.error("addNeutronPort failed. {}", port, e);
             return false;
         }
         return true;
     }
 
+    public static boolean addL3EndpointForExternalGateway(TenantId tenantId, L3ContextId l3ContextId,
+            IpAddress ipAddress, NetworkDomainId networkContainment, ReadWriteTransaction rwTx) {
+
+        EndpointL3Key epL3Key = new EndpointL3Key(ipAddress, l3ContextId);
+        addNeutronExtGwGbpMapping(epL3Key, rwTx);
+        List<EndpointGroupId> epgIds = new ArrayList<>();
+        // each EP has to be in EPG ANY, except dhcp and router
+        epgIds.add(MappingUtils.EPG_EXTERNAL_ID);
+        epgIds.add(MappingUtils.EPG_ANY_ID);
+        EndpointL3 epL3 = createL3Endpoint(tenantId, epL3Key, epgIds, networkContainment);
+        InstanceIdentifier<EndpointL3> iid_l3 = IidFactory.endpointL3Iid(l3ContextId, ipAddress);
+        rwTx.put(LogicalDatastoreType.OPERATIONAL, iid_l3, epL3, true);
+        return true;
+    }
+
+    private static void addNeutronExtGwGbpMapping(EndpointL3Key epL3Key, ReadWriteTransaction rwTx) {
+            ExternalGatewayAsL3Endpoint externalGatewayL3Endpoint = MappingFactory.createExternalGatewayByL3Endpoint(epL3Key);
+            rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.externalGatewayAsL3Endpoint(epL3Key.getL3Context(), epL3Key.getIpAddress()),
+                    externalGatewayL3Endpoint, true);
+    }
+
     private static void addNeutronGbpMapping(NeutronPort port, EndpointKey epKey, ReadWriteTransaction rwTx) {
+        UniqueId portId = new UniqueId(port.getID());
         if (isRouterInterfacePort(port)) {
             LOG.trace("Adding RouterInterfacePort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
-            UniqueId portId = new UniqueId(port.getID());
             EndpointByRouterInterfacePort endpointByPort = MappingFactory.createEndpointByRouterInterfacePort(epKey,
                     portId);
-            rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointByRouterInterfacePortIid(portId),
+            rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByRouterInterfacePortIid(portId),
                     endpointByPort, true);
             RouterInterfacePortByEndpoint portByEndpoint = MappingFactory.createRouterInterfacePortByEndpoint(portId,
                     epKey);
             rwTx.put(LogicalDatastoreType.OPERATIONAL,
-                    IidFactory.routerInterfacePortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
+                    NeutronGbpIidFactory.routerInterfacePortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
                     portByEndpoint, true);
         } else if (isRouterGatewayPort(port)) {
             LOG.trace("Adding RouterGatewayPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
-            UniqueId portId = new UniqueId(port.getID());
             EndpointByRouterGatewayPort endpointByPort = MappingFactory.createEndpointByRouterGatewayPort(epKey, portId);
-            rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointByRouterGatewayPortIid(portId),
+            rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByRouterGatewayPortIid(portId),
                     endpointByPort, true);
             RouterGatewayPortByEndpoint portByEndpoint = MappingFactory.createRouterGatewayPortByEndpoint(portId, epKey);
             rwTx.put(LogicalDatastoreType.OPERATIONAL,
-                    IidFactory.routerGatewayPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
+                    NeutronGbpIidFactory.routerGatewayPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
+                    portByEndpoint, true);
+        } else if (isFloatingIpPort(port)) {
+            LOG.trace("Adding FloatingIpPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
+            EndpointByFloatingIpPort endpointByPort = MappingFactory.createEndpointByFloatingIpPort(epKey, portId);
+            rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByFloatingIpPortIid(portId),
+                    endpointByPort, true);
+            FloatingIpPortByEndpoint portByEndpoint = MappingFactory.createFloatingIpPortByEndpoint(portId, epKey);
+            rwTx.put(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.floatingIpPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()),
                     portByEndpoint, true);
         } else {
             LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getID(),
                     port.getDeviceOwner(), epKey);
-            UniqueId portId = new UniqueId(port.getID());
             EndpointByPort endpointByPort = MappingFactory.createEndpointByPort(epKey, portId);
-            rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointByPortIid(portId), endpointByPort, true);
+            rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), endpointByPort, true);
             PortByEndpoint portByEndpoint = MappingFactory.createPortByEndpoint(portId, epKey);
             rwTx.put(LogicalDatastoreType.OPERATIONAL,
-                    IidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint, true);
+                    NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint, true);
         }
     }
 
@@ -318,13 +356,16 @@ public class NeutronPortAware implements INeutronPortAware {
             return null;
         }
         IpPrefix ipSubnet = potentialSubnet.get().getIpPrefix();
-        NeutronSecurityRule dhcpRuleEgress = createDhcpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, true);
-        NeutronSecurityRule dhcpRuleIngress = createDhcpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, false);
-        return ImmutableList.of(dhcpRuleEgress, dhcpRuleIngress);
+        List<NeutronSecurityRule> rules = new ArrayList<>();
+        rules.add(createDhcpIngressSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId));
+        rules.add(createDnsSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId));
+        rules.add(createUdpEgressSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId));
+        rules.add(createIcmpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, true));
+        rules.add(createIcmpSecRule(port.getID(), tenantId, ipSubnet, consumerEpgId, false));
+        return rules;
     }
 
-    private NeutronSecurityRule createDhcpSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId,
-            boolean isEgress) {
+    private NeutronSecurityRule createDhcpIngressSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId) {
         NeutronSecurityRule dhcpSecRule = new NeutronSecurityRule();
         dhcpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
         dhcpSecRule.setSecurityRuleTenantID(tenantId.getValue());
@@ -332,17 +373,29 @@ public class NeutronPortAware implements INeutronPortAware {
         if (consumerEpgId != null) {
             dhcpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
         }
-        if (isEgress) {
-            dhcpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "__" + ruleUuid);
-            dhcpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
-            dhcpSecRule.setSecurityRulePortMin(DHCP_CLIENT_PORT);
-            dhcpSecRule.setSecurityRulePortMax(DHCP_CLIENT_PORT);
+        dhcpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_dhcp__" + ruleUuid);
+        dhcpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        dhcpSecRule.setSecurityRulePortMin(DHCP_SERVER_PORT);
+        dhcpSecRule.setSecurityRulePortMax(DHCP_SERVER_PORT);
+        dhcpSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
+        if (ipSubnet.getIpv4Prefix() != null) {
+            dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
         } else {
-            dhcpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "__" + ruleUuid);
-            dhcpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
-            dhcpSecRule.setSecurityRulePortMin(DHCP_SERVER_PORT);
-            dhcpSecRule.setSecurityRulePortMax(DHCP_SERVER_PORT);
+            dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
+        }
+        return dhcpSecRule;
+    }
+
+    private NeutronSecurityRule createUdpEgressSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId) {
+        NeutronSecurityRule dhcpSecRule = new NeutronSecurityRule();
+        dhcpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
+        dhcpSecRule.setSecurityRuleTenantID(tenantId.getValue());
+        dhcpSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
+        if (consumerEpgId != null) {
+            dhcpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
         }
+        dhcpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "_udp__" + ruleUuid);
+        dhcpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
         dhcpSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
         if (ipSubnet.getIpv4Prefix() != null) {
             dhcpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
@@ -352,6 +405,52 @@ public class NeutronPortAware implements INeutronPortAware {
         return dhcpSecRule;
     }
 
+    private NeutronSecurityRule createDnsSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId) {
+        NeutronSecurityRule dnsSecRule = new NeutronSecurityRule();
+        dnsSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
+        dnsSecRule.setSecurityRuleTenantID(tenantId.getValue());
+        dnsSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
+        if (consumerEpgId != null) {
+            dnsSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
+        }
+        dnsSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_dns__" + ruleUuid);
+        dnsSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        dnsSecRule.setSecurityRulePortMin(DNS_SERVER_PORT);
+        dnsSecRule.setSecurityRulePortMax(DNS_SERVER_PORT);
+        dnsSecRule.setSecurityRuleProtocol(NeutronUtils.UDP);
+        if (ipSubnet.getIpv4Prefix() != null) {
+            dnsSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        } else {
+            dnsSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
+        }
+        return dnsSecRule;
+    }
+
+    private NeutronSecurityRule createIcmpSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId,
+            boolean isEgress) {
+        NeutronSecurityRule icmpSecRule = new NeutronSecurityRule();
+        icmpSecRule.setSecurityRuleGroupID(MappingUtils.EPG_DHCP_ID.getValue());
+        icmpSecRule.setSecurityRuleTenantID(tenantId.getValue());
+        icmpSecRule.setSecurityRuleRemoteIpPrefix(Utils.getStringIpPrefix(ipSubnet));
+        if (consumerEpgId != null) {
+            icmpSecRule.setSecurityRemoteGroupID(consumerEpgId.getValue());
+        }
+        if (isEgress) {
+            icmpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "_icmp__" + ruleUuid);
+            icmpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS);
+        } else {
+            icmpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "_icmp__" + ruleUuid);
+            icmpSecRule.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        }
+        icmpSecRule.setSecurityRuleProtocol(NeutronUtils.ICMP);
+        if (ipSubnet.getIpv4Prefix() != null) {
+            icmpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        } else {
+            icmpSecRule.setSecurityRuleEthertype(NeutronUtils.IPv6);
+        }
+        return icmpSecRule;
+    }
+
     /**
      * @see org.opendaylight.neutron.spi.INeutronPortAware#canUpdatePort(org.opendaylight.neutron.spi.NeutronPort,
      *      org.opendaylight.neutron.spi.NeutronPort)
@@ -386,7 +485,7 @@ public class NeutronPortAware implements INeutronPortAware {
             LOG.trace("Port is router gateway - {}", port.getID());
             return;
         }
-        if (isFloatingIp(port)) {
+        if (isFloatingIpPort(port)) {
             LOG.trace("Port is floating ip - {}", port.getID());
             return;
         }
@@ -504,16 +603,27 @@ public class NeutronPortAware implements INeutronPortAware {
                     NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
             return;
         }
-        ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
+        if (isRouterGatewayPort(port)) {
+            LOG.trace("Port is router gateway - {} does nothing. {} handles router iface.",
+                    NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName());
+            return;
+        }
+        if (isFloatingIpPort(port)) {
+            LOG.trace("Port is floating ip - {} device id - {}", port.getID(), port.getDeviceID());
+            floatingIpPortByDeviceId.remove(port.getDeviceID());
+        }
+        ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
         TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID()));
         L2FloodDomainId l2FdId = new L2FloodDomainId(port.getNetworkUUID());
-        ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rTx);
+        ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
         boolean isFwCtxValid = validateForwardingCtx(fwCtx);
         if (!isFwCtxValid) {
-            rTx.close();
+            rwTx.cancel();
             return;
         }
 
+        EndpointKey epKey = new EndpointKey(fwCtx.getL2BridgeDomain().getId(), new MacAddress(port.getMacAddress()));
+        deleteNeutronGbpMapping(port, epKey, rwTx);
         UnregisterEndpointInput unregisterEpRpcInput = createUnregisterEndpointInput(port, fwCtx);
         try {
             RpcResult<Void> rpcResult = epService.unregisterEndpoint(unregisterEpRpcInput).get();
@@ -522,8 +632,36 @@ public class NeutronPortAware implements INeutronPortAware {
             }
         } catch (InterruptedException | ExecutionException e) {
             LOG.error("addPort - RPC invocation failed.", e);
-        } finally {
-            rTx.close();
+            rwTx.cancel();
+        }
+    }
+
+    private static void deleteNeutronGbpMapping(NeutronPort port, EndpointKey epKey, ReadWriteTransaction rwTx) {
+        UniqueId portId = new UniqueId(port.getID());
+        if (isRouterInterfacePort(port)) {
+            LOG.trace("Adding RouterInterfacePort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.endpointByRouterInterfacePortIid(portId), rwTx);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.routerInterfacePortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
+        } else if (isRouterGatewayPort(port)) {
+            LOG.trace("Adding RouterGatewayPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.endpointByRouterGatewayPortIid(portId), rwTx);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.routerGatewayPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
+        } else if (isFloatingIpPort(port)) {
+            LOG.trace("Adding FloatingIpPort-Endpoint mapping for port {} and endpoint {}", port.getID(), epKey);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.endpointByFloatingIpPortIid(portId), rwTx);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.floatingIpPortByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
+        } else {
+            LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getID(),
+                    port.getDeviceOwner(), epKey);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), rwTx);
+            DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+                    NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), rwTx);
         }
     }
 
@@ -549,6 +687,20 @@ public class NeutronPortAware implements INeutronPortAware {
         return inputBuilder.build();
     }
 
+    private static EndpointL3 createL3Endpoint(TenantId tenantId, EndpointL3Key epL3Key,
+            List<EndpointGroupId> epgIds, NetworkDomainId containment) {
+
+        EndpointL3Builder epL3Builder = new EndpointL3Builder()
+        .setTenant(tenantId)
+        .setNetworkContainment(containment)
+        .setIpAddress(epL3Key.getIpAddress())
+        .setL3Context(epL3Key.getL3Context())
+        .setEndpointGroups(epgIds)
+        .setTimestamp(System.currentTimeMillis());
+
+        return epL3Builder.build();
+    }
+
     private static RegisterEndpointInput createRegisterEndpointInput(NeutronPort port, ForwardingCtx fwCtx) {
         List<EndpointGroupId> epgIds = new ArrayList<>();
         // each EP has to be in EPG ANY, except dhcp and router
@@ -644,7 +796,7 @@ public class NeutronPortAware implements INeutronPortAware {
         return DEVICE_OWNER_ROUTER_GATEWAY.equals(port.getDeviceOwner());
     }
 
-    private static boolean isFloatingIp(NeutronPort port) {
+    private static boolean isFloatingIpPort(NeutronPort port) {
         return DEVICE_OWNER_FLOATING_IP.equals(port.getDeviceOwner());
     }
 
@@ -690,6 +842,8 @@ public class NeutronPortAware implements INeutronPortAware {
         return l3s;
     }
 
-
+    public static UniqueId getFloatingIpPortIdByDeviceId(String deviceId) {
+        return floatingIpPortByDeviceId.get(deviceId);
+    }
 
 }