+ 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());
+ // router interface port can have only one IP
+ Optional<FixedIps> potentialPortIpWithSubnet = PortUtils.resolveFirstFixedIps(port);
+ if (!potentialPortIpWithSubnet.isPresent()) {
+ LOG.warn("Illegal state - router interface port does not contain fixed IPs {}", port);
+ return;
+ }
+ FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
+ L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue());
+ // change L3Context for all new EPs with same subnet as router port
+ changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), port.getNetworkId(),
+ new Uuid(port.getDeviceId()), newNeutron, false);
+ // set L3Context as parent for bridge domain which is parent of subnet
+ TenantId tenantId = new TenantId(port.getTenantId().getValue());
+ Optional<Subnet> potentialRouterPortSubnet =
+ SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(), oldNeutron.getSubnets());
+ if (!potentialRouterPortSubnet.isPresent()) {
+ LOG.warn("Illegal state - router interface port is in subnet which does not exist. {}", port);
+ return;
+ }
+ ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+ Subnet routerPortSubnet = potentialRouterPortSubnet.get();
+ modifyForwardingOnDelete(routerPortSubnet, l3Context, tenantId, rwTx);
+ ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
+ ForwardingContext fwdCtx = new ForwardingContextBuilder().setContextId(l2BdId)
+ .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
+ .setParent(MappingUtils.createParent(l3Context, MappingUtils.L3_CONTEXT))
+ .build();
+ rwTx.merge(LogicalDatastoreType.CONFIGURATION,
+ L2L3IidFactory.l2BridgeDomainIid(tenantId, fwdCtx.getContextId()), fwdCtx);
+ NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, newNeutron, null);
+ rwTx.put(LogicalDatastoreType.CONFIGURATION,
+ L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()), subnet);
+ 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());
+ ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+ unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
+ unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx,
+ removeBaseEpMapping);
+ DataStoreHelper.submitToDs(rwTx);
+ if (!oldNeutron.getPorts()
+ .getPort()
+ .stream()
+ .filter(PortUtils::isDhcpPort)
+ .anyMatch(p -> !p.getUuid().equals(port.getUuid()))) {
+ Port metadataPort = cloneMetadataPortFromDhcpPort(port, metadataIpPrefix);
+ if (PortUtils.resolveFirstFixedIps(metadataPort).isPresent()) {
+ ContextId metadataCtx = resolveL3ContextForPort(metadataPort,
+ PortUtils.resolveFirstFixedIps(metadataPort).get(), oldNeutron);
+ AddressEndpointUnregBuilder metadataEpUnreg =
+ new AddressEndpointUnregBuilder().setAddress(String.valueOf(metadataIpPrefix.getValue()))
+ .setAddressType(IpPrefixType.class)
+ .setContextType(MappingUtils.L3_CONTEXT)
+ .setContextId(metadataCtx);
+ epRegistrator.unregisterEndpoint(metadataEpUnreg.build());
+ }
+ }
+ } else if (PortUtils.isNormalPort(port)) {
+ LOG.trace("Port is normal port: {}", port.getUuid().getValue());
+ ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+ unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
+ unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx,
+ removeBaseEpMapping);
+ DataStoreHelper.submitToDs(rwTx);
+ } else if (PortUtils.isRouterGatewayPort(port)) {
+ // do nothing because actual trigger is detaching of port from router
+ LOG.trace("Port is router gateway port: {}", port.getUuid().getValue());
+ } else if (PortUtils.isFloatingIpPort(port)) {
+ // do nothing because trigger is floating IP
+ LOG.trace("Port is floating ip: {}", port.getUuid().getValue());
+ } else {
+ LOG.warn("Unknown port: {}", port);
+ }