introducing loopback port for VPP
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronPortAware.java
index da1ab83b6fae18b2b67b832926c589498abeae8d..454b4dea38eda59bd72c631c911b884c769b5325 100644 (file)
@@ -74,6 +74,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gb
 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.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.neutron.binding.rev150712.PortBindingExtension;
 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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
@@ -113,6 +114,45 @@ public class NeutronPortAware implements NeutronAware<Port> {
             }
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
             ContextId routerL3Context = new ContextId(port.getDeviceId());
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+
+            AddressEndpointKey addrEpKey = new AddressEndpointKey(port.getMacAddress().getValue(),
+                MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
+            UniqueId portId = new UniqueId(port.getUuid().getValue());
+            addBaseEndpointMappings(addrEpKey, portId, rwTx);
+
+            // Add Qrouter and VPProuter port as Endpoint
+            if (port.getAugmentation(PortBindingExtension.class) != null &&
+                PortUtils.DEVICE_VIF_TYPE.equals(port.getAugmentation(PortBindingExtension.class).getVifType())) {
+                LOG.trace("Port is QRouter port: {}", port.getUuid().getValue());
+                Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
+                if (!firstFixedIps.isPresent()) {
+                    LOG.warn("QRouter port does not have an IP address. {}", port);
+                    return;
+                }
+
+                FixedIps ipWithSubnet = firstFixedIps.get();
+                NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
+                List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
+                epgsFromSecGroups.add(NetworkService.EPG_ID);
+
+                // BUILD BASE ENDPOINT
+                AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(port, networkContainment,
+                    epgsFromSecGroups);
+                AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(port, networkContainment,
+                    epgsFromSecGroups, neutron);
+                setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
+
+                // BUILD ENDPOINT
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder
+                    epInBuilder =
+                    createEndpointRegFromPort(
+                        port, ipWithSubnet, networkContainment, epgsFromSecGroups, neutron);
+                registerBaseEndpointAndStoreMapping(
+                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx);
+                registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
+            }
+
             // change L3Context for all EPs with same subnet as router port
             changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), neutron);
             // set L3Context as parent for bridge domain which is parent of subnet
@@ -124,7 +164,6 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 return;
             }
             Subnet routerPortSubnet = potentialRouterPortSubnet.get();
-            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
             ForwardingContext l2Bd = new ForwardingContextBuilder().setContextId(l2BdId)
                 .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
@@ -136,11 +175,6 @@ public class NeutronPortAware implements NeutronAware<Port> {
                     routerPortSubnet, portIpWithSubnet.getIpAddress());
             rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain);
 
-            AddressEndpointKey addrEpKey = new AddressEndpointKey(port.getMacAddress().getValue(),
-                    MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
-            UniqueId portId = new UniqueId(port.getUuid().getValue());
-            addBaseEndpointMappings(addrEpKey, portId, rwTx);
-
             // does the same for tenant forwarding domains
             processTenantForwarding(routerPortSubnet, routerL3Context, portIpWithSubnet, tenantId, rwTx);
 
@@ -256,14 +290,15 @@ public class NeutronPortAware implements NeutronAware<Port> {
     private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Neutron neutron) {
         Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts());
         for (Port portInSameSubnet : portsInSameSubnet) {
-            if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)) {
+            if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)
+                || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
                 // endpoints are created only from neutron normal port or DHCP port
                 Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(portInSameSubnet);
                 if (firstFixedIps.isPresent()) {
                     // endpoint has only one network containment therefore only first IP is used
                     FixedIps ipWithSubnet = firstFixedIps.get();
                     List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
-                    if (PortUtils.isDhcpPort(portInSameSubnet)) {
+                    if (PortUtils.isDhcpPort(portInSameSubnet) || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
                         endpointGroupIds.add(NetworkService.EPG_ID);
                     } else if (PortUtils.isNormalPort(portInSameSubnet)) {
                         endpointGroupIds.add(NetworkClient.EPG_ID);
@@ -280,7 +315,9 @@ public class NeutronPortAware implements NeutronAware<Port> {
                         .setContextType(l3BaseEp.getContextType())
                         .build();
                     epRegistrator.unregisterEndpoint(addrEpUnreg);
-                    epRegistrator.registerEndpoint(l3BaseEp.build());
+                    RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder()
+                        .setAddressEndpointReg(ImmutableList.of(l2BaseEp.build(), l3BaseEp.build())).build();
+                    epRegistrator.registerEndpoint(regBaseEpInput);
 
                     modifyL3ContextForEndpoints(portInSameSubnet, ipWithSubnet, l3BaseEp.getContextId());
                 }