X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=neutron-mapper%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgroupbasedpolicy%2Fneutron%2Fmapper%2Fmapping%2FNeutronPortAware.java;h=ee22c5729e4d4a8b88b0997a069a79589fd3f377;hb=refs%2Fchanges%2F93%2F31593%2F8;hp=4f391e3be5cd9d1999308f62054d99c952d9ebb5;hpb=6dc8cae407853253137978c53eca7bd61676b943;p=groupbasedpolicy.git 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 4f391e3be..ee22c5729 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 @@ -11,57 +11,78 @@ 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; 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.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.infrastructure.NetworkClient; +import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService; +import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.Router; +import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.NeutronSecurityGroupAware; +import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware; 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; import org.opendaylight.neutron.spi.NeutronSecurityRule; 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.yang.types.rev100924.MacAddress; 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.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; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterL3PrefixEndpointInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterL3PrefixEndpointInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoint.fields.L3Address; 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.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.ports.EndpointByPortBuilder; +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.ports.by.endpoints.PortByEndpointBuilder; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContextInput; 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; @@ -77,14 +98,19 @@ public class NeutronPortAware implements INeutronPortAware { public static final Logger LOG = LoggerFactory.getLogger(NeutronPortAware.class); private static final String DEVICE_OWNER_DHCP = "network:dhcp"; private static final String DEVICE_OWNER_ROUTER_IFACE = "network:router_interface"; - private static final int DHCP_CLIENT_PORT = 68; - private static final int DHCP_SERVER_PORT = 67; + private static final String DEVICE_OWNER_ROUTER_GATEWAY = "network:router_gateway"; + private static final String DEVICE_OWNER_FLOATING_IP = "network:floatingip"; private final DataBroker dataProvider; private final EndpointService epService; + private final NeutronSecurityRuleAware secRuleAware; + private final NeutronSecurityGroupAware secGrpAware; + private final static Map floatingIpPortByDeviceId = new HashMap<>(); - public NeutronPortAware(DataBroker dataProvider, EndpointService epService) { + public NeutronPortAware(DataBroker dataProvider, EndpointService epService, NeutronSecurityRuleAware secRuleAware, NeutronSecurityGroupAware secGrpAware) { this.dataProvider = checkNotNull(dataProvider); this.epService = checkNotNull(epService); + this.secRuleAware = checkNotNull(secRuleAware); + this.secGrpAware = secGrpAware; } /** @@ -113,24 +139,28 @@ public class NeutronPortAware implements INeutronPortAware { NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName()); return; } + 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.put(port.getDeviceID(), new UniqueId(port.getID())); + return; + } ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID())); if (isDhcpPort(port)) { - LOG.trace("Port is DHCP port."); - List dhcpSecRules = createDhcpSecRules(port, null, rwTx); - if (dhcpSecRules == null) { + LOG.trace("Port is DHCP port. - {}", port.getID()); + Neutron_IPs firstIp = MappingUtils.getFirstIp(port.getFixedIPs()); + if (firstIp == null) { + LOG.warn("Illegal state - DHCP port does not have an IP address."); rwTx.cancel(); return; } - - for (NeutronSecurityRule dhcpSecRule : dhcpSecRules) { - boolean isDhcpSecRuleAdded = NeutronSecurityRuleAware.addNeutronSecurityRule(dhcpSecRule, rwTx); - if (!isDhcpSecRuleAdded) { - rwTx.cancel(); - return; - } - } } else { + // this is here b/c stable/kilo sends sec-groups only with port List secGroups = port.getSecurityGroups(); if (secGroups != null) { for (NeutronSecurityGroup secGroup : secGroups) { @@ -138,35 +168,22 @@ public class NeutronPortAware implements INeutronPortAware { Optional potentialEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, epgId), rwTx); if (!potentialEpg.isPresent()) { - boolean isSecGroupCreated = NeutronSecurityGroupAware.addNeutronSecurityGroup(secGroup, rwTx); + boolean isSecGroupCreated = secGrpAware.addNeutronSecurityGroup(secGroup, rwTx); if (!isSecGroupCreated) { rwTx.cancel(); return; } - if (containsSecRuleWithRemoteSecGroup(secGroup)) { - List dhcpSecRules = createDhcpSecRules(port, epgId, rwTx); - if (dhcpSecRules == null) { - rwTx.cancel(); - return; - } - List routerSecRules = NeutronRouterAware.createRouterSecRules(port, epgId, rwTx); - if (routerSecRules == null) { - rwTx.cancel(); - return; - } - } } else { List secRules = secGroup.getSecurityRules(); if (secRules != null) { for (NeutronSecurityRule secRule : secRules) { - NeutronSecurityRuleAware.addNeutronSecurityRule(secRule, rwTx); + secRuleAware.addNeutronSecurityRule(secRule, rwTx); } } } } } } - boolean isNeutronPortCreated = addNeutronPort(port, rwTx, epService); if (!isNeutronPortCreated) { rwTx.cancel(); @@ -185,26 +202,108 @@ public class NeutronPortAware implements INeutronPortAware { return false; } EndpointKey epKey = new EndpointKey(fwCtx.getL2BridgeDomain().getId(), new MacAddress(port.getMacAddress())); - UniqueId portId = new UniqueId(port.getID()); - EndpointByPort endpointByPort = createEndpointByPort(epKey, portId); - rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.endpointByPortIid(portId), endpointByPort); - PortByEndpoint portByEndpoint = createPortByEndpoint(portId, epKey); - rwTx.put(LogicalDatastoreType.OPERATIONAL, - IidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint); + addNeutronGbpMapping(port, epKey, rwTx); try { RegisterEndpointInput registerEpRpcInput = createRegisterEndpointInput(port, fwCtx); - RpcResult 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("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 epgIds = new ArrayList<>(); + // each EP has to be in EPG ANY, except dhcp and router + epgIds.add(MappingUtils.EPG_EXTERNAL_ID); + epgIds.add(Router.EPG_ID); + EndpointL3 epL3 = createL3Endpoint(tenantId, epL3Key, epgIds, networkContainment); + InstanceIdentifier iid_l3 = IidFactory.l3EndpointIid(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); + EndpointByRouterInterfacePort endpointByPort = MappingFactory.createEndpointByRouterInterfacePort(epKey, + portId); + rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByRouterInterfacePortIid(portId), + endpointByPort, true); + RouterInterfacePortByEndpoint portByEndpoint = MappingFactory.createRouterInterfacePortByEndpoint(portId, + epKey); + rwTx.put(LogicalDatastoreType.OPERATIONAL, + 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); + EndpointByRouterGatewayPort endpointByPort = MappingFactory.createEndpointByRouterGatewayPort(epKey, portId); + rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByRouterGatewayPortIid(portId), + endpointByPort, true); + RouterGatewayPortByEndpoint portByEndpoint = MappingFactory.createRouterGatewayPortByEndpoint(portId, epKey); + rwTx.put(LogicalDatastoreType.OPERATIONAL, + 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); + EndpointByPort endpointByPort = MappingFactory.createEndpointByPort(epKey, portId); + rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.endpointByPortIid(portId), endpointByPort, true); + PortByEndpoint portByEndpoint = MappingFactory.createPortByEndpoint(portId, epKey); + rwTx.put(LogicalDatastoreType.OPERATIONAL, + NeutronGbpIidFactory.portByEndpointIid(epKey.getL2Context(), epKey.getMacAddress()), portByEndpoint, true); + } + } + + public static boolean addL3PrefixEndpoint(L3ContextId l3ContextId, IpPrefix ipPrefix, IpAddress ipAddress, TenantId tenantId, + EndpointService epService) { + EndpointL3PrefixKey epL3PrefixKey = new EndpointL3PrefixKey( ipPrefix, l3ContextId); + EndpointL3Key epL3Key = null; + List l3Gateways = new ArrayList<>(); + if (ipAddress != null) { + epL3Key = new EndpointL3Key(ipAddress, l3ContextId); + l3Gateways.add(epL3Key); + } + try { + RegisterL3PrefixEndpointInput registerL3PrefixEpRpcInput = createRegisterL3PrefixEndpointInput(epL3PrefixKey, l3Gateways,tenantId); + + RpcResult rpcResult = epService.registerL3PrefixEndpoint(registerL3PrefixEpRpcInput).get(); + if (!rpcResult.isSuccessful()) { + LOG.warn("Illegal state - RPC registerEndpoint failed. Input of RPC: {}", registerL3PrefixEpRpcInput); + return false; + } } catch (InterruptedException | ExecutionException e) { LOG.error("addPort - RPC invocation failed.", e); return false; } return true; + } private static boolean validateForwardingCtx(ForwardingCtx fwCtx) { @@ -223,69 +322,6 @@ public class NeutronPortAware implements INeutronPortAware { return true; } - private static EndpointByPort createEndpointByPort(EndpointKey epKey, UniqueId portId) { - return new EndpointByPortBuilder().setPortId(portId) - .setL2Context(epKey.getL2Context()) - .setMacAddress(epKey.getMacAddress()) - .build(); - } - - private static PortByEndpoint createPortByEndpoint(UniqueId portId, EndpointKey epKey) { - return new PortByEndpointBuilder().setPortId(portId) - .setL2Context(epKey.getL2Context()) - .setMacAddress(epKey.getMacAddress()) - .build(); - } - - private List createDhcpSecRules(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 - DHCP port does not have an IP address."); - return null; - } - SubnetId dhcpSubnetId = new SubnetId(firstIp.getSubnetUUID()); - Optional potentialSubnet = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, - IidFactory.subnetIid(tenantId, dhcpSubnetId), rTx); - if (!potentialSubnet.isPresent()) { - LOG.warn("Illegal state - Subnet {} where is DHCP port does not exist.", dhcpSubnetId.getValue()); - 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); - } - - private NeutronSecurityRule createDhcpSecRule(String ruleUuid, TenantId tenantId, IpPrefix ipSubnet, EndpointGroupId consumerEpgId, - boolean isEgress) { - 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()); - } - if (isEgress) { - dhcpSecRule.setSecurityRuleUUID(NeutronUtils.EGRESS + "__" + ruleUuid); - dhcpSecRule.setSecurityRuleDirection(NeutronUtils.EGRESS); - dhcpSecRule.setSecurityRulePortMin(DHCP_CLIENT_PORT); - dhcpSecRule.setSecurityRulePortMax(DHCP_CLIENT_PORT); - } else { - dhcpSecRule.setSecurityRuleUUID(NeutronUtils.INGRESS + "__" + 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.setSecurityRuleEthertype(NeutronUtils.IPv6); - } - return dhcpSecRule; - } - /** * @see org.opendaylight.neutron.spi.INeutronPortAware#canUpdatePort(org.opendaylight.neutron.spi.NeutronPort, * org.opendaylight.neutron.spi.NeutronPort) @@ -316,6 +352,19 @@ public class NeutronPortAware implements INeutronPortAware { NeutronPortAware.class.getSimpleName(), NeutronRouterAware.class.getSimpleName()); return; } + if (isRouterGatewayPort(port)) { + LOG.trace("Port is router gateway - {}", port.getID()); + return; + } + if (isFloatingIpPort(port)) { + LOG.trace("Port is floating ip - {}", port.getID()); + return; + } + if (Strings.isNullOrEmpty(port.getTenantID())) { + LOG.trace("REMOVE ME: Tenant is null - {}", port.getID()); + return; + } + ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction(); TenantId tenantId = new TenantId(Utils.normalizeUuid(port.getTenantID())); MacAddress macAddress = new MacAddress(port.getMacAddress()); @@ -425,41 +474,115 @@ 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; } UnregisterEndpointInput unregisterEpRpcInput = createUnregisterEndpointInput(port, fwCtx); + boolean isEndpointUnregistered = false; try { - RpcResult rpcResult = epService.unregisterEndpoint(unregisterEpRpcInput).get(); - if (!rpcResult.isSuccessful()) { - LOG.warn("Illegal state - RPC unregisterEndpoint failed. Input of RPC: {}", unregisterEpRpcInput); - } + isEndpointUnregistered = epService.unregisterEndpoint(unregisterEpRpcInput).get().isSuccessful(); } catch (InterruptedException | ExecutionException e) { - LOG.error("addPort - RPC invocation failed.", e); - } finally { - rTx.close(); + LOG.error("unregisterEndpoint - RPC invocation failed.", e); + } + if (isEndpointUnregistered) { + EndpointKey epKey = new EndpointKey(fwCtx.getL2BridgeDomain().getId(), new MacAddress(port.getMacAddress())); + deleteNeutronGbpMapping(port, epKey, rwTx); + DataStoreHelper.submitToDs(rwTx); + } else { + LOG.warn("Illegal state - RPC unregisterEndpoint failed. Input of RPC: {}", unregisterEpRpcInput); + 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); + } + } + + private static RegisterL3PrefixEndpointInput createRegisterL3PrefixEndpointInput(EndpointL3PrefixKey key, List endpointL3Keys, TenantId tenantId) { + List epgIds = new ArrayList<>(); + List l3Gateways = new ArrayList(); + for (EndpointL3Key epL3Key : endpointL3Keys) { + EndpointL3Gateways l3Gateway = new EndpointL3GatewaysBuilder().setIpAddress(epL3Key.getIpAddress()) + .setL3Context(epL3Key.getL3Context()) + .build(); + l3Gateways.add(l3Gateway); + } + RegisterL3PrefixEndpointInputBuilder inputBuilder = new RegisterL3PrefixEndpointInputBuilder() + .setL3Context(key.getL3Context()) + .setIpPrefix(key.getIpPrefix()) + .setEndpointGroups(epgIds) + .setTenant(tenantId) + .setEndpointL3Gateways(l3Gateways) + .setTimestamp(System.currentTimeMillis()); + return inputBuilder.build(); + } + + private static EndpointL3 createL3Endpoint(TenantId tenantId, EndpointL3Key epL3Key, + List 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 epgIds = new ArrayList<>(); - // each EP has to be in EPG ANY, except dhcp and router if (isDhcpPort(port)) { - epgIds.add(MappingUtils.EPG_DHCP_ID); - } else if (!containsSecRuleWithRemoteSecGroup(port.getSecurityGroups())) { - epgIds.add(MappingUtils.EPG_ANY_ID); + epgIds.add(NetworkService.EPG_ID); } List securityGroups = port.getSecurityGroups(); if ((securityGroups == null || securityGroups.isEmpty())) { - if (!isDhcpPort(port)) { + if (isFloatingIpPort(port)) { + epgIds.add(MappingUtils.EPG_EXTERNAL_ID); + } else if (!isDhcpPort(port)) { LOG.warn( "Port {} does not contain any security group. The port should belong to 'default' security group at least.", port.getPortUUID()); @@ -468,6 +591,7 @@ public class NeutronPortAware implements INeutronPortAware { for (NeutronSecurityGroup secGrp : securityGroups) { epgIds.add(new EndpointGroupId(secGrp.getSecurityGroupUUID())); } + epgIds.add(NetworkClient.EPG_ID); } RegisterEndpointInputBuilder inputBuilder = new RegisterEndpointInputBuilder().setL2Context( fwCtx.getL2BridgeDomain().getId()) @@ -475,7 +599,9 @@ public class NeutronPortAware implements INeutronPortAware { .setTenant(new TenantId(Utils.normalizeUuid(port.getTenantID()))) .setEndpointGroups(epgIds) .addAugmentation(OfOverlayContextInput.class, - new OfOverlayContextInputBuilder().setPortName(createTapPortName(port)).build()) + new OfOverlayContextInputBuilder() + .setPortName(createTapPortName(port)) + .build()) .setTimestamp(System.currentTimeMillis()); List fixedIPs = port.getFixedIPs(); // TODO Li msunal this getting of just first IP has to be rewrite when OFOverlay renderer @@ -494,32 +620,6 @@ public class NeutronPortAware implements INeutronPortAware { return inputBuilder.build(); } - private static boolean containsSecRuleWithRemoteSecGroup(List secGroups) { - if (secGroups == null) { - return false; - } - for (NeutronSecurityGroup secGroup : secGroups) { - boolean containsSecRuleWithRemoteSecGroup = containsSecRuleWithRemoteSecGroup(secGroup); - if (containsSecRuleWithRemoteSecGroup) { - return true; - } - } - return false; - } - - private static boolean containsSecRuleWithRemoteSecGroup(NeutronSecurityGroup secGroup) { - List secRules = secGroup.getSecurityRules(); - if (secRules == null) { - return false; - } - for (NeutronSecurityRule secRule : secRules) { - if (!Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) { - return true; - } - } - return false; - } - private static Name createTapPortName(NeutronPort port) { return new Name("tap" + port.getID().substring(0, 11)); } @@ -532,6 +632,14 @@ public class NeutronPortAware implements INeutronPortAware { return DEVICE_OWNER_ROUTER_IFACE.equals(port.getDeviceOwner()); } + private static boolean isRouterGatewayPort(NeutronPort port) { + return DEVICE_OWNER_ROUTER_GATEWAY.equals(port.getDeviceOwner()); + } + + private static boolean isFloatingIpPort(NeutronPort port) { + return DEVICE_OWNER_FLOATING_IP.equals(port.getDeviceOwner()); + } + private UnregisterEndpointInput createUnregisterEndpointInput(Endpoint ep) { UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder(); L2 l2Ep = new L2Builder().setL2Context(ep.getL2Context()).setMacAddress(ep.getMacAddress()).build(); @@ -574,4 +682,8 @@ public class NeutronPortAware implements INeutronPortAware { return l3s; } + public static UniqueId getFloatingIpPortIdByDeviceId(String deviceId) { + return floatingIpPortByDeviceId.get(deviceId); + } + }