vpnmanager: drop nullToEmpty and reqNonNullOrElse
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / SubnetRoutePacketInHandler.java
index a8511a2804c00a83306a6c480f1062cb038f19e8..d2999f300cb22b3d618286138a8c4c80cb530373 100644 (file)
@@ -14,6 +14,7 @@ import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -29,16 +30,17 @@ import org.opendaylight.genius.mdsalutil.packet.IPv4;
 import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
 import org.opendaylight.netvirt.vpnmanager.api.ICentralizedSwitchProvider;
 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
+import org.opendaylight.netvirt.vpnmanager.iplearn.ipv4.ArpUtils;
 import org.opendaylight.netvirt.vpnmanager.utilities.VpnManagerCounters;
 import org.opendaylight.openflowplugin.libraries.liblldp.BitBufferHelper;
 import org.opendaylight.openflowplugin.libraries.liblldp.BufferException;
 import org.opendaylight.openflowplugin.libraries.liblldp.HexEncode;
-import org.opendaylight.openflowplugin.libraries.liblldp.NetUtils;
 import org.opendaylight.openflowplugin.libraries.liblldp.Packet;
 import org.opendaylight.openflowplugin.libraries.liblldp.PacketException;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
@@ -51,6 +53,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
@@ -70,12 +73,13 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
     private final IInterfaceManager interfaceManager;
     private final VpnManagerCounters vpnManagerCounters;
     private final Ipv6NdUtilService ipv6NdUtilService;
+    private final VpnUtil vpnUtil;
 
     @Inject
     public SubnetRoutePacketInHandler(final DataBroker dataBroker, final PacketProcessingService packetService,
             final OdlInterfaceRpcService odlInterfaceRpcService,
             final ICentralizedSwitchProvider centralizedSwitchProvider, final IInterfaceManager interfaceManager,
-            VpnManagerCounters vpnManagerCounters, final Ipv6NdUtilService ipv6NdUtilService) {
+            VpnManagerCounters vpnManagerCounters, final Ipv6NdUtilService ipv6NdUtilService, VpnUtil vpnUtil) {
         this.dataBroker = dataBroker;
         this.packetService = packetService;
         this.odlInterfaceRpcService = odlInterfaceRpcService;
@@ -83,6 +87,7 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
         this.interfaceManager = interfaceManager;
         this.vpnManagerCounters = vpnManagerCounters;
         this.ipv6NdUtilService = ipv6NdUtilService;
+        this.vpnUtil = vpnUtil;
     }
 
     @Override
@@ -90,6 +95,10 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
 
         short tableId = notification.getTableId().getValue();
         LOG.trace("{} onPacketReceived: Packet punted from table {}", LOGGING_PREFIX, tableId);
+        if (!vpnUtil.isArpLearningEnabled()) {
+            LOG.trace("Not handling packet as ARP Based Learning is disabled");
+            return;
+        }
         byte[] data = notification.getPayload();
         if (notification.getMatch() == null || notification.getMatch().getMetadata() == null) {
             LOG.error("{} onPacketReceived: Received from table {} where the match or metadata are null",
@@ -102,7 +111,7 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
         if (tableId == NwConstants.L3_SUBNET_ROUTE_TABLE) {
             LOG.trace("{} onPacketReceived: Some packet received as {}", LOGGING_PREFIX, notification);
             try {
-                res.deserialize(data, 0, data.length * NetUtils.NUM_BITS_IN_A_BYTE);
+                res.deserialize(data, 0, data.length * Byte.SIZE);
             } catch (PacketException e) {
                 LOG.error("{} onPacketReceived: Failed to decode Packet ", LOGGING_PREFIX, e);
                 vpnManagerCounters.subnetRoutePacketFailed();
@@ -176,7 +185,9 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
         }
 
         String vpnIdVpnInstanceName = vpnIdsOptional.get().getVpnInstanceName();
-        if (VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnIdVpnInstanceName, dstIpStr) != null) {
+        VpnPortipToPort persistedIP =
+                vpnUtil.getNeutronPortFromVpnPortFixedIp(vpnIdVpnInstanceName, dstIpStr);
+        if (persistedIP != null && !persistedIP.isLearntIp()) {
             vpnManagerCounters.subnetRoutePacketIgnored();
             LOG.info("{} onPacketReceived: IP Packet received with Target IP {} source IP {} vpnId {} "
                     + "is a valid Neutron port,ignoring subnet route processing", LOGGING_PREFIX, dstIpStr,
@@ -184,7 +195,7 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
             return;
         }
 
-        if (VpnUtil.getLearntVpnVipToPort(dataBroker, vpnIdVpnInstanceName, dstIpStr) != null) {
+        if (vpnUtil.getLearntVpnVipToPort(vpnIdVpnInstanceName, dstIpStr) != null) {
             vpnManagerCounters.subnetRoutePacketIgnored();
             LOG.info("{} onPacketReceived: IP Packet received with Target IP {} source Ip {} vpnId {}"
                     + " is an already discovered IPAddress, ignoring subnet route processing",
@@ -215,8 +226,7 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
         LOG.info("{} handleBgpVpnSubnetRoute: Processing IP Packet received with Source IP {} and Target IP {}"
                 + " and elan Tag {}", LOGGING_PREFIX, srcIpStr, dstIpStr, elanTag);
         SubnetOpDataEntry targetSubnetForPacketOut =
-                getTargetSubnetForPacketOut(dataBroker, elanTag, dstIpStr);
-
+                getTargetSubnetForPacketOut(elanTag, dstIpStr);
         if (targetSubnetForPacketOut != null) {
             // Handle subnet routes ip requests
             transmitArpOrNsPacket(targetSubnetForPacketOut.getNhDpnId(), srcIpStr, srcMac, dstIp, dstIpStr, elanTag);
@@ -230,11 +240,11 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
     private void handleInternalVpnSubnetRoutePacket(BigInteger metadata, byte[] dstIp, String srcIpStr, String dstIpStr,
             String vpnIdVpnInstanceName, long elanTag)
             throws InterruptedException, ExecutionException, UnknownHostException {
-        String vmVpnInterfaceName = VpnUtil.getVpnInterfaceName(odlInterfaceRpcService, metadata);
+        String vmVpnInterfaceName = vpnUtil.getVpnInterfaceName(metadata);
         if (isTunnel(vmVpnInterfaceName)) {
             handlePacketFromTunnelToExternalNetwork(vpnIdVpnInstanceName, srcIpStr, dstIp, dstIpStr, elanTag);
         }
-        VpnInterface vmVpnInterface = VpnUtil.getVpnInterface(dataBroker, vmVpnInterfaceName);
+        VpnInterface vmVpnInterface = vpnUtil.getVpnInterface(vmVpnInterfaceName);
         if (vmVpnInterface == null) {
             LOG.error("Vpn interface {} doesn't exist.", vmVpnInterfaceName);
             vpnManagerCounters.subnetRoutePacketFailed();
@@ -242,13 +252,12 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
         }
         if (VpnHelper.doesVpnInterfaceBelongToVpnInstance(vpnIdVpnInstanceName,
                vmVpnInterface.getVpnInstanceNames())
-               && !VpnUtil.isBgpVpnInternet(dataBroker, vpnIdVpnInstanceName)) {
+               && !vpnUtil.isBgpVpnInternet(vpnIdVpnInstanceName)) {
             LOG.trace("Unknown IP is in internal network");
             handlePacketToInternalNetwork(dstIp, dstIpStr, elanTag);
         } else {
             LOG.trace("Unknown IP is in external network");
-            String vpnName =
-                    VpnUtil.getInternetVpnFromVpnInstanceList(dataBroker, vmVpnInterface.getVpnInstanceNames());
+            String vpnName = vpnUtil.getInternetVpnFromVpnInstanceList(vmVpnInterface.getVpnInstanceNames());
             if (vpnName != null) {
                 handlePacketToExternalNetwork(new Uuid(vpnIdVpnInstanceName), vpnName, dstIp, dstIpStr, elanTag);
             } else {
@@ -264,8 +273,8 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
             String dstIpAddress, long elanTag) throws UnknownHostException {
         long groupid = VpnUtil.getRemoteBCGroup(elanTag);
         if (NWUtil.isIpv4Address(dstIpAddress)) {
-            LOG.debug("Sending ARP: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}", sourceIpAddress, sourceMac,
-                    dstIpAddress, dpnId, elanTag);
+            LOG.debug("Sending ARP: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}, groupid={}", sourceIpAddress,
+                    sourceMac, dstIpAddress, dpnId, elanTag, groupid);
             vpnManagerCounters.subnetRoutePacketArpSent();
 
             TransmitPacketInput packetInput =
@@ -274,8 +283,8 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
             JdkFutures.addErrorLogging(packetService.transmitPacket(packetInput), LOG, "Transmit packet");
         } else {
             // IPv6 case
-            LOG.debug("Sending NS: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}", sourceIpAddress, sourceMac,
-                    dstIpAddress, dpnId, elanTag);
+            LOG.debug("Sending NS: srcIp={}, srcMac={}, dstIp={}, dpId={}, elan-tag={}, groupid={}", sourceIpAddress,
+                    sourceMac, dstIpAddress, dpnId, elanTag, groupid);
             vpnManagerCounters.subnetRoutePacketNsSent();
 
             VpnUtil.sendNeighborSolicationToOfGroup(this.ipv6NdUtilService, new Ipv6Address(sourceIpAddress),
@@ -287,7 +296,7 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
             throws UnknownHostException {
         try {
             SubnetOpDataEntry targetSubnetForPacketOut =
-                    getTargetSubnetForPacketOut(dataBroker, elanTag, dstIpStr);
+                    getTargetSubnetForPacketOut(elanTag, dstIpStr);
 
             if (targetSubnetForPacketOut == null) {
                 LOG.debug("Couldn't find matching subnet for elan tag {} and destination ip {}", elanTag, dstIpStr);
@@ -327,17 +336,18 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
     }
 
     private void handlePacketFromTunnelToExternalNetwork(String vpnIdVpnInstanceName, String srcIpStr, byte[] dstIp,
-            String dstIpStr, long elanTag) throws UnknownHostException {
-        String routerId = VpnUtil.getAssociatedExternalRouter(dataBroker, srcIpStr);
+        String dstIpStr, long elanTag) throws UnknownHostException {
+        String routerId = vpnUtil.getAssociatedExternalRouter(srcIpStr);
         if (null == routerId) {
             LOG.debug("This ip is not associated with any external router: {}", srcIpStr);
+            return;
         }
         handlePacketToExternalNetwork(new Uuid(vpnIdVpnInstanceName), routerId, dstIp, dstIpStr, elanTag);
     }
 
     private void handlePacketToExternalNetwork(Uuid vpnInstanceNameUuid, String routerId, byte[] dstIp, String dstIpStr,
             long elanTag) throws UnknownHostException {
-        Routers externalRouter = VpnUtil.getExternalRouter(dataBroker, routerId);
+        Routers externalRouter = vpnUtil.getExternalRouter(routerId);
         if (externalRouter == null) {
             vpnManagerCounters.subnetRoutePacketFailed();
             LOG.debug("{} handlePacketToExternalNetwork: Can't find external router with id {}", LOGGING_PREFIX,
@@ -375,15 +385,16 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
     }
 
     // return only the first VPN subnetopdataentry
-    private static SubnetOpDataEntry getTargetSubnetForPacketOut(DataBroker broker, long elanTag, String ipAddress) {
-        ElanTagName elanInfo = VpnUtil.getElanInfoByElanTag(broker, elanTag);
+    @Nullable
+    private SubnetOpDataEntry getTargetSubnetForPacketOut(long elanTag, String ipAddress) {
+        ElanTagName elanInfo = vpnUtil.getElanInfoByElanTag(elanTag);
         if (elanInfo == null) {
             LOG.error("{} getTargetDpnForPacketOut: Unable to retrieve ElanInfo for elanTag {}", LOGGING_PREFIX,
                     elanTag);
             return null;
         }
         try {
-            Optional<NetworkMap> optionalNetworkMap = SingleTransactionDataBroker.syncReadOptional(broker,
+            Optional<NetworkMap> optionalNetworkMap = SingleTransactionDataBroker.syncReadOptional(dataBroker,
                     LogicalDatastoreType.CONFIGURATION, VpnUtil.buildNetworkMapIdentifier(new Uuid(
                             elanInfo.getName())));
             if (!optionalNetworkMap.isPresent()) {
@@ -394,30 +405,32 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
             List<Uuid> subnetList = optionalNetworkMap.get().getSubnetIdList();
             LOG.debug("{} getTargetDpnForPacketOut: Obtained subnetList as {} for network {}", LOGGING_PREFIX,
                     subnetList, elanInfo.getName());
-            for (Uuid subnetId : subnetList) {
-                String vpnName = null;
-                Subnetmap sn = VpnUtil.getSubnetmapFromItsUuid(broker, subnetId);
-                if (sn != null && sn.getVpnId() != null) {
-                    vpnName = sn.getVpnId().getValue();
-                }
-                if (vpnName == null) {
-                    continue;
-                }
-                Optional<SubnetOpDataEntry> optionalSubs;
-                optionalSubs = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.OPERATIONAL,
-                        VpnUtil.buildSubnetOpDataEntryInstanceIdentifier(subnetId));
-                if (!optionalSubs.isPresent()) {
-                    continue;
-                }
-                SubnetOpDataEntry subOpEntry = optionalSubs.get();
-                if (subOpEntry.getNhDpnId() != null) {
-                    LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {}", LOGGING_PREFIX, subnetId.getValue());
-                    IpPrefix cidr = new IpPrefix(subOpEntry.getSubnetCidr().toCharArray());
-                    boolean match = NWUtil.isIpAddressInRange(new IpAddress(ipAddress.toCharArray()), cidr);
-                    LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {} matching {}", LOGGING_PREFIX,
+            if (subnetList != null) {
+                for (Uuid subnetId : subnetList) {
+                    String vpnName = null;
+                    Subnetmap sn = vpnUtil.getSubnetmapFromItsUuid(subnetId);
+                    if (sn != null && sn.getVpnId() != null) {
+                        vpnName = sn.getVpnId().getValue();
+                    }
+                    if (vpnName == null) {
+                        continue;
+                    }
+                    Optional<SubnetOpDataEntry> optionalSubs = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                        LogicalDatastoreType.OPERATIONAL, VpnUtil.buildSubnetOpDataEntryInstanceIdentifier(subnetId));
+                    if (!optionalSubs.isPresent()) {
+                        continue;
+                    }
+                    SubnetOpDataEntry subOpEntry = optionalSubs.get();
+                    if (subOpEntry.getNhDpnId() != null) {
+                        LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {}", LOGGING_PREFIX,
+                            subnetId.getValue());
+                        IpPrefix cidr = IpPrefixBuilder.getDefaultInstance(subOpEntry.getSubnetCidr());
+                        boolean match = NWUtil.isIpAddressInRange(IpAddressBuilder.getDefaultInstance(ipAddress), cidr);
+                        LOG.trace("{} getTargetDpnForPacketOut: Viewing Subnet {} matching {}", LOGGING_PREFIX,
                             subnetId.getValue(), match);
-                    if (match) {
-                        return subOpEntry;
+                        if (match) {
+                            return subOpEntry;
+                        }
                     }
                 }
             }
@@ -429,9 +442,6 @@ public class SubnetRoutePacketInHandler implements PacketProcessingListener {
     }
 
     public boolean isTunnel(String interfaceName) {
-        org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
-            .ietf.interfaces.rev140508.interfaces.Interface configIface =
-            interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName);
-        return configIface.augmentation(IfTunnel.class) != null;
+        return interfaceManager.getInterfaceInfoFromConfigDataStore(interfaceName).augmentation(IfTunnel.class) != null;
     }
 }