introducing loopback port for VPP
[groupbasedpolicy.git] / neutron-vpp-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / vpp / mapper / processors / PortHandler.java
index decd0567f199415f7607752a22f303e21b9c451f..560d1556613de73e8ac23eb4ea396c5cea410e57 100644 (file)
@@ -18,6 +18,8 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;\r
 import org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.SocketInfo;\r
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;\r
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.UniqueId;\r
@@ -30,6 +32,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_render
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.LoopbackCase;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.LoopbackCaseBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.TapCase;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.TapCaseBuilder;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;\r
@@ -37,10 +41,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.P
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;\r
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;\r
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;\r
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;\r
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;\r
@@ -56,6 +64,8 @@ import org.slf4j.LoggerFactory;
 import com.google.common.annotations.VisibleForTesting;\r
 import com.google.common.base.Optional;\r
 \r
+import java.util.List;\r
+\r
 public class PortHandler implements TransactionChainListener {\r
 \r
     private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class);\r
@@ -189,15 +199,59 @@ public class PortHandler implements TransactionChainListener {
                     .setName(createQRouterPortName(port.getUuid()))\r
                     .build();\r
             vppEpBuilder.setInterfaceTypeChoice(tapCase);\r
+        } else if (isValidVppRouterPort(port)) {\r
+            vppEpBuilder.setInterfaceTypeChoice(getLoopbackCase(port));\r
         }\r
         return vppEpBuilder.build();\r
     }\r
 \r
+    private LoopbackCase getLoopbackCase(Port port) {\r
+        LoopbackCaseBuilder loopbackCase = new LoopbackCaseBuilder()\r
+            .setPhysAddress(new PhysAddress(port.getMacAddress().getValue()));\r
+        Optional<FixedIps> fixedIpsOptional = resolveFirstFixedIps(port);\r
+        if(fixedIpsOptional.isPresent() && fixedIpsOptional.get().getIpAddress() != null){\r
+            loopbackCase.setIpAddress(fixedIpsOptional.get().getIpAddress());\r
+            ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
+            Optional<Subnet> subnetOptional =\r
+                DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+                    InstanceIdentifier.builder(Neutron.class)\r
+                        .child(Subnets.class)\r
+                        .child(Subnet.class, new SubnetKey(fixedIpsOptional.get().getSubnetId()))\r
+                        .build(), rTx);\r
+            if (subnetOptional.isPresent()) {\r
+                Ipv4Prefix ipv4Prefix = subnetOptional.get().getCidr().getIpv4Prefix();\r
+                loopbackCase.setIpPrefix(new IpPrefix(ipv4Prefix));\r
+            } else {\r
+                LOG.warn("IpPrefix for loopback port: {} was not set.", port);\r
+            }\r
+            if (loopbackCase.getIpAddress() != null && loopbackCase.getIpPrefix() != null) {\r
+                loopbackCase.setBvi(true);\r
+                LOG.trace("Creating loopback BVI interface: {} for VPP router port: {}.", loopbackCase, port);\r
+            }\r
+\r
+        } else {\r
+            LOG.warn("IpAddress for loopback port: {} was not set.", port);\r
+        }\r
+        return loopbackCase.build();\r
+    }\r
+\r
     /**\r
      * If Qrouter (L3 Agent) is in use, any of Openstack neutron routers is not going be mapped\r
      * to ODL neutron.\r
      */\r
     private boolean isValidQRouterPort(Port port) {\r
+        Optional<Router> optRouter = getRouterOptional(port);\r
+        return !optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
+                && port.getMacAddress() != null;\r
+    }\r
+\r
+    private boolean isValidVppRouterPort(Port port) {\r
+        Optional<Router> optRouter = getRouterOptional(port);\r
+        return optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
+            && port.getMacAddress() != null;\r
+    }\r
+\r
+    private Optional<Router> getRouterOptional(Port port) {\r
         ReadOnlyTransaction rTx = transactionChain.newReadOnlyTransaction();\r
         InstanceIdentifier<Router> routerIid = InstanceIdentifier.builder(Neutron.class)\r
             .child(Routers.class)\r
@@ -205,8 +259,15 @@ public class PortHandler implements TransactionChainListener {
             .build();\r
         Optional<Router> optRouter = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, routerIid, rTx);\r
         rTx.close();\r
-        return !optRouter.isPresent() && port.getDeviceOwner().contains(ROUTER_OWNER)\r
-                && port.getMacAddress() != null;\r
+        return optRouter;\r
+    }\r
+\r
+    public static Optional<FixedIps> resolveFirstFixedIps(Port port) {\r
+        List<FixedIps> fixedIps = port.getFixedIps();\r
+        if (fixedIps != null && !fixedIps.isEmpty()) {\r
+            return Optional.of(fixedIps.get(0));\r
+        }\r
+        return Optional.absent();\r
     }\r
 \r
     private String createPortName(Uuid portUuid) {\r
@@ -277,6 +338,6 @@ public class PortHandler implements TransactionChainListener {
 \r
     @Override\r
     public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {\r
-        LOG.trace("Transaction chain was successfull. {}", chain);\r
+        LOG.trace("Transaction chain was successful. {}", chain);\r
     }\r
 }\r