ONOS-4713, ONOS-4715 issues merge to master

Change-Id: I3e52af949005529cec18a85e49601c47f7e386f8
diff --git a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/SfcFlowRuleInstallerService.java b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/SfcFlowRuleInstallerService.java
index caff305..e76a578 100644
--- a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/SfcFlowRuleInstallerService.java
+++ b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/SfcFlowRuleInstallerService.java
@@ -64,4 +64,15 @@
      */
     ConnectPoint unInstallLoadBalancedFlowRules(PortChain portChain, FiveTuple fiveTuple,
             NshServicePathId nshSpiId);
+
+    /**
+     * Uninstall load balanced classifier rules.
+     *
+     * @param portChain port-chain
+     * @param fiveTuple five tuple packet information
+     * @param nshSpiId service path index identifier
+     * @return connectPoint the network identifier
+     */
+    ConnectPoint unInstallLoadBalancedClassifierRules(PortChain portChain, FiveTuple fiveTuple,
+            NshServicePathId nshSpiId);
 }
diff --git a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java
index 71397a7..59329c4 100644
--- a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java
+++ b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/installer/impl/SfcFlowRuleInstallerImpl.java
@@ -218,6 +218,20 @@
         return installSfcFlowRules(portChain, fiveTuple, nshSpiId, Objective.Operation.REMOVE);
     }
 
+    @Override
+    public ConnectPoint unInstallLoadBalancedClassifierRules(PortChain portChain, FiveTuple fiveTuple,
+            NshServicePathId nshSpiId) {
+        checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
+
+        List<PortPairId> portPairs = portChain.getLoadBalancePath(fiveTuple);
+        // Get the first port pair
+        ListIterator<PortPairId> portPairListIterator = portPairs.listIterator();
+        PortPairId portPairId = portPairListIterator.next();
+        PortPair portPair = portPairService.getPortPair(portPairId);
+
+        return installSfcClassifierRules(portChain, portPair, nshSpiId, fiveTuple, Objective.Operation.REMOVE);
+    }
+
     public ConnectPoint installSfcFlowRules(PortChain portChain, FiveTuple fiveTuple, NshServicePathId nshSpiId,
             Objective.Operation type) {
         checkNotNull(portChain, PORT_CHAIN_NOT_NULL);
@@ -634,7 +648,10 @@
                 treatment.extension(tunnelDsttreatment, deviceId);
                 treatment.transition(TUNNEL_SEND_TABLE);
                 sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
-                classifierList.add(deviceIdfromPortPair);
+
+                selector.matchInPort(PortNumber.CONTROLLER);
+                sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
+                classifierList.add(deviceId);
 
                 installSfcTunnelSendRule(deviceId, nshSpiId, type);
                 installSfcTunnelReceiveRule(deviceIdfromPortPair, nshSpiId, type);
@@ -646,6 +663,9 @@
                                                                              nshSpiId, flowClassifier);
                 treatment.transition(ENCAP_OUTPUT_TABLE);
                 sendSfcRule(selector, treatment, deviceIdfromPortPair, type, flowClassifier.priority());
+
+                selector.matchInPort(PortNumber.CONTROLLER);
+                sendSfcRule(selector, treatment, deviceId, type, flowClassifier.priority());
                 classifierList.add(deviceIdfromPortPair);
             }
         }
diff --git a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
index 3292e23..171195e 100644
--- a/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
+++ b/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java
@@ -316,13 +316,15 @@
         Set<FiveTuple> fiveTupleSet = portChain.getLoadBalanceIdMapKeys();
         for (FiveTuple fiveTuple : fiveTupleSet) {
             id = portChain.getLoadBalanceId(fiveTuple);
+            nshSpi = NshServicePathId.of(getNshServicePathId(id, nshSpiId));
             if (processedIdList.contains(id)) {
-                // multiple five tuple can have single path.
+                // Multiple five tuple can have single path. In this case only
+                // the classifier rule need to delete
+                flowRuleInstaller.unInstallLoadBalancedClassifierRules(portChain, fiveTuple, nshSpi);
                 continue;
             } else {
                 processedIdList.add(id);
             }
-            nshSpi = NshServicePathId.of(getNshServicePathId(id, nshSpiId));
             flowRuleInstaller.unInstallLoadBalancedFlowRules(portChain, fiveTuple, nshSpi);
         }
 
@@ -507,6 +509,7 @@
             int portDst = 0;
             byte protocol = 0;
             MacAddress macSrc = packet.getSourceMAC();
+            MacAddress macDst = packet.getDestinationMAC();
             TenantId tenantId = getTenantId(macSrc);
 
             if (ethType == Ethernet.TYPE_IPV4) {
@@ -539,6 +542,8 @@
                     .setPortDst(PortNumber.portNumber(portDst))
                     .setProtocol(protocol)
                     .setTenantId(tenantId)
+                    .setMacSrc(macSrc)
+                    .setMacDst(macDst)
                     .build();
 
             PortChainId portChainId = findPortChainFromFiveTuple(fiveTuple);
@@ -577,13 +582,12 @@
          * Send packet back to classifier.
          *
          * @param context packet context
-         * @param connectPoint connect point of first service function
          */
         private void sendPacket(PacketContext context) {
 
             ConnectPoint sourcePoint = context.inPacket().receivedFrom();
 
-            TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(sourcePoint.port()).build();
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(PortNumber.TABLE).build();
             OutboundPacket packet = new DefaultOutboundPacket(sourcePoint.deviceId(), treatment, context.inPacket()
                     .unparsed());
             packetService.emit(packet);
diff --git a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
index cc2c265..e51c699 100644
--- a/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
+++ b/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortAdapter.java
@@ -16,16 +16,17 @@
 package org.onosproject.sfc.util;
 
 import java.util.Collection;
-import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.onlab.packet.IpAddress;
 import org.onosproject.net.DeviceId;
 import org.onosproject.vtnrsc.FixedIp;
 import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
 import org.onosproject.vtnrsc.VirtualPort;
 import org.onosproject.vtnrsc.VirtualPortId;
-import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.virtualport.VirtualPortListener;
 import org.onosproject.vtnrsc.virtualport.VirtualPortService;
 
 /**
@@ -95,4 +96,12 @@
     public boolean removePorts(Iterable<VirtualPortId> vPortIds) {
         return true;
     }
+
+    @Override
+    public void addListener(VirtualPortListener listener) {
+    }
+
+    @Override
+    public void removeListener(VirtualPortListener listener) {
+    }
 }