MRI version bumpup for Aluminium
[netvirt.git] / elanmanager / api / src / main / java / org / opendaylight / netvirt / elan / arp / responder / ArpResponderUtil.java
index 7434eb219a718c137e557939c61186966e2ca195..63eabadcf4e9f0814cb981126beb4212f2969127 100644 (file)
@@ -12,18 +12,18 @@ import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Supplier;
 import java.util.stream.Collectors;
-
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
-import org.opendaylight.genius.mdsalutil.GroupEntity;
 import org.opendaylight.genius.mdsalutil.InstructionInfo;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.MatchInfo;
@@ -37,12 +37,10 @@ import org.opendaylight.genius.mdsalutil.actions.ActionMoveSourceDestinationEth;
 import org.opendaylight.genius.mdsalutil.actions.ActionMoveSpaToTpa;
 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
-import org.opendaylight.genius.mdsalutil.actions.ActionPuntToController;
 import org.opendaylight.genius.mdsalutil.actions.ActionSetArpOp;
 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldEthernetSource;
 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
-import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.genius.mdsalutil.matches.MatchArpOp;
 import org.opendaylight.genius.mdsalutil.matches.MatchArpTpa;
 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
@@ -50,16 +48,19 @@ import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -70,48 +71,19 @@ public final class ArpResponderUtil {
 
     private static final Logger LOG = LoggerFactory.getLogger(ArpResponderUtil.class);
 
-    private static final long WAIT_TIME_FOR_SYNC_INSTALL = Long.getLong("wait.time.sync.install", 300L);
-
     /**
      * A Utility class.
      */
     private ArpResponderUtil() {
     }
 
-    /**
-     * Install Group flow on the DPN.
-     *
-     * @param mdSalManager
-     *            Reference of MDSAL API RPC that provides API for installing
-     *            group flow
-     * @param dpnId
-     *            DPN on which group flow to be installed
-     * @param groupdId
-     *            Uniquely identifiable Group Id for the group flow
-     * @param groupName
-     *            Name of the group flow
-     * @param buckets
-     *            List of the bucket actions for the group flow
-     */
-    public static void installGroup(IMdsalApiManager mdSalManager, BigInteger dpnId, long groupdId, String groupName,
-            List<BucketInfo> buckets) {
-        LOG.trace("Installing group flow on dpn {}", dpnId);
-        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupdId, groupName, GroupTypes.GroupAll, buckets);
-        mdSalManager.syncInstallGroup(groupEntity);
-        try {
-            Thread.sleep(WAIT_TIME_FOR_SYNC_INSTALL);
-        } catch (InterruptedException e1) {
-            LOG.warn("Error while waiting for ARP Responder Group Entry to be installed on DPN {} ", dpnId);
-        }
-    }
-
     /**
      * Get Default ARP Responder Drop flow on the DPN.
      *
      * @param dpnId
      *            DPN on which group flow to be installed
      */
-    public static FlowEntity getArpResponderTableMissFlow(BigInteger dpnId) {
+    public static FlowEntity getArpResponderTableMissFlow(Uint64 dpnId) {
         return MDSALUtil.buildFlowEntity(dpnId, NwConstants.ARP_RESPONDER_TABLE,
                 String.valueOf(NwConstants.ARP_RESPONDER_TABLE), NwConstants.TABLE_MISS_PRIORITY,
                 ArpResponderConstant.DROP_FLOW_NAME.value(), 0, 0, NwConstants.COOKIE_ARP_RESPONDER,
@@ -123,27 +95,20 @@ public final class ArpResponderUtil {
      * Get Bucket Actions for ARP Responder Group Flow.
      *
      * <p>
-     * Install Default Groups, Group has 3 Buckets
+     * Install Default Groups, Group has 1 Bucket
      * </p>
      * <ul>
-     * <li>Punt to controller</li>
-     * <li>Resubmit to Table {@link NwConstants#LPORT_DISPATCHER_TABLE}, for
-     * ELAN flooding
      * <li>Resubmit to Table {@link NwConstants#ARP_RESPONDER_TABLE}, for ARP
      * Auto response from DPN itself</li>
      * </ul>
      *
      * @param resubmitTableId
      *            Resubmit Flow Table Id
-     * @param resubmitTableId2
-     *            Resubmit Flow Table Id
      * @return List of bucket actions
      */
-    public static List<BucketInfo> getDefaultBucketInfos(short resubmitTableId, short resubmitTableId2) {
-        return Arrays.asList(
-                new BucketInfo(Collections.singletonList(new ActionPuntToController())),
-                new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId))),
-                new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId2))));
+    public static List<BucketInfo> getDefaultBucketInfos(short resubmitTableId) {
+        return Collections.singletonList(
+            new BucketInfo(Collections.singletonList(new ActionNxResubmit(resubmitTableId))));
     }
 
     /**
@@ -173,8 +138,8 @@ public final class ArpResponderUtil {
     public static List<MatchInfo> getMatchCriteria(int lportTag, ElanInstance elanInstance,
             String ipAddress) {
 
-        BigInteger metadata = ElanHelper.getElanMetadataLabel(elanInstance.getElanTag(), lportTag);
-        BigInteger metadataMask = ElanHelper.getElanMetadataMask();
+        Uint64 metadata = ElanHelper.getElanMetadataLabel(elanInstance.getElanTag().toJava(), lportTag);
+        Uint64 metadataMask = ElanHelper.getElanMetadataMask();
         return Arrays.asList(MatchEthernetType.ARP, MatchArpOp.REQUEST, new MatchArpTpa(ipAddress, "32"),
                 new MatchMetadata(metadata, metadataMask));
 
@@ -193,12 +158,14 @@ public final class ArpResponderUtil {
      *            MacAddress for which ARP Response packet is to be generated
      * @return List of ARP Responder Actions actions
      */
-    public static List<Action> getActions(IInterfaceManager ifaceMgrRpcService, String ifName, String ipAddress,
-            String macAddress) {
+    private static List<Action> getActions(IInterfaceManager ifaceMgrRpcService, ItmRpcService itmRpcService,
+                                           String ifName, String ipAddress, String macAddress,
+                                           boolean isTunnelInterface) {
 
         AtomicInteger actionCounter = new AtomicInteger();
         List<Action> actions = arpActions.apply(actionCounter, macAddress, ipAddress);
-        actions.addAll(getEgressActionsForInterface(ifaceMgrRpcService, ifName, actionCounter.get()));
+        actions.addAll(getEgressActionsForInterface(ifaceMgrRpcService, itmRpcService, ifName, actionCounter.get(),
+                isTunnelInterface));
         LOG.trace("Total Number of actions is {}", actionCounter);
         return actions;
 
@@ -245,7 +212,7 @@ public final class ArpResponderUtil {
                 new ActionMoveSpaToTpa().buildAction(actionCounter.getAndIncrement()),
                 new ActionLoadMacToSha(new MacAddress(mac)).buildAction(actionCounter.getAndIncrement()),
                 new ActionLoadIpToSpa(ip).buildAction(actionCounter.getAndIncrement()),
-                new ActionNxLoadInPort(BigInteger.ZERO).buildAction(actionCounter.getAndIncrement()));
+                new ActionNxLoadInPort(Uint64.valueOf(BigInteger.ZERO)).buildAction(actionCounter.getAndIncrement()));
         return actions;
 
     };
@@ -254,8 +221,9 @@ public final class ArpResponderUtil {
      * Get instruction list for ARP responder flows.
      */
     public static List<Instruction> getInterfaceInstructions(IInterfaceManager ifaceMgrRpcService, String interfaceName,
-            String ipAddress, String macAddress) {
-        List<Action> actions = ArpResponderUtil.getActions(ifaceMgrRpcService, interfaceName, ipAddress, macAddress);
+            String ipAddress, String macAddress, ItmRpcService itmRpcService) {
+        List<Action> actions = ArpResponderUtil.getActions(ifaceMgrRpcService, itmRpcService, interfaceName, ipAddress,
+                macAddress, false);
         return Collections.singletonList(MDSALUtil.buildApplyActionsInstruction(actions));
     }
 
@@ -269,15 +237,18 @@ public final class ArpResponderUtil {
      * action needs to be replaced with goto instruction.
      */
     public static List<Instruction> getExtInterfaceInstructions(IInterfaceManager ifaceMgrRpcService,
-            String extInterfaceName, String ipAddress, String macAddress) {
+                                                                ItmRpcService itmRpcService,
+                                                                String extInterfaceName, String ipAddress,
+                                                                String macAddress) {
         AtomicInteger tableId = new AtomicInteger(-1);
         List<Instruction> instructions = new ArrayList<>();
-        List<Action> actions = getActions(ifaceMgrRpcService, extInterfaceName, ipAddress, macAddress);
+        List<Action> actions = getActions(ifaceMgrRpcService, itmRpcService, extInterfaceName, ipAddress, macAddress,
+                false);
         actions.removeIf(v -> {
             org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = v
                     .getAction();
             if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
-                tableId.set(((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable());
+                tableId.set(((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable().toJava());
                 return true;
             } else {
                 return false;
@@ -300,51 +271,6 @@ public final class ArpResponderUtil {
         return instructions;
     }
 
-    /**
-     * Install ARP Responder FLOW.
-     *
-     * @param mdSalManager
-     *            Reference of MDSAL API RPC that provides API for installing
-     *            flow
-     * @param dpnId
-     *            DPN on which flow to be installed
-     * @param flowId
-     *            Uniquely Identifiable Arp Responder Table flow Id
-     * @param flowName
-     *            Readable flow name
-     * @param priority
-     *            Flow Priority
-     * @param cookie
-     *            Flow Cookie
-     * @param matches
-     *            List of Match Criteria for the flow
-     * @param instructions
-     *            List of Instructions for the flow
-     */
-    public static void installFlow(IMdsalApiManager mdSalManager, BigInteger dpnId, String flowId, String flowName,
-            int priority, BigInteger cookie, List<MatchInfo> matches, List<Instruction> instructions) {
-        Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.ARP_RESPONDER_TABLE, flowId, priority, flowName, 0, 0,
-                cookie, matches, instructions);
-        mdSalManager.installFlow(dpnId, flowEntity);
-    }
-
-    /**
-     * Remove flow form DPN.
-     *
-     * @param mdSalManager
-     *            Reference of MDSAL API RPC that provides API for installing
-     *            flow
-     * @param dpnId
-     *            DPN form which flow to be removed
-     * @param flowId
-     *            Uniquely Identifiable Arp Responder Table flow Id that is to
-     *            be removed
-     */
-    public static void removeFlow(IMdsalApiManager mdSalManager, BigInteger dpnId, String flowId) {
-        Flow flowEntity = MDSALUtil.buildFlow(NwConstants.ARP_RESPONDER_TABLE, flowId);
-        mdSalManager.removeFlow(dpnId, flowEntity);
-    }
-
     /**
      * Creates Uniquely Identifiable flow Id.
      *
@@ -375,16 +301,15 @@ public final class ArpResponderUtil {
      *            Gateway IP for which ARP Response flow to be installed
      * @return Cookie
      */
-    public static BigInteger generateCookie(int lportTag, String ipAddress) {
+    public static Uint64 generateCookie(int lportTag, String ipAddress) {
         LOG.trace("IPAddress in long {}", ipAddress);
-        BigInteger cookie = NwConstants.COOKIE_ARP_RESPONDER.add(BigInteger.valueOf(255))
-                .add(BigInteger.valueOf(ipTolong(ipAddress)));
-        return cookie.add(BigInteger.valueOf(lportTag));
+        return Uint64.fromLongBits(NwConstants.COOKIE_ARP_RESPONDER.longValue()
+                + 255 + ipTolong(ipAddress) + lportTag);
     }
 
-    private static BigInteger buildCookie(short tableId, int arpOpType) {
-        return NwConstants.COOKIE_ARP_RESPONDER.add(BigInteger.ONE).add(
-                BigInteger.valueOf(tableId).add(BigInteger.valueOf(arpOpType)));
+    private static Uint64 buildCookie(short tableId, int arpOpType) {
+        return Uint64.fromLongBits(NwConstants.COOKIE_ARP_RESPONDER.longValue()
+                + 1 + tableId + arpOpType);
     }
 
     private static String buildFlowRef(short tableId, int arpOpType) {
@@ -394,7 +319,7 @@ public final class ArpResponderUtil {
                 + (arpOpType == NwConstants.ARP_REQUEST ? "arp.request" : "arp.replay");
     }
 
-    public static FlowEntity createArpDefaultFlow(BigInteger dpId, short tableId, int arpOpType,
+    public static FlowEntity createArpDefaultFlow(Uint64 dpId, short tableId, int arpOpType,
             Supplier<List<MatchInfo>> matches, Supplier<List<ActionInfo>> actions) {
 
         List<InstructionInfo> instructions = Collections.singletonList(new InstructionApplyActions(actions.get()));
@@ -441,11 +366,30 @@ public final class ArpResponderUtil {
      *            Action Key
      * @return List of Egress Actions
      */
-    public static List<Action> getEgressActionsForInterface(IInterfaceManager ifaceMgrRpcService, String ifName,
-            int actionCounter) {
-        List<ActionInfo> actionInfos = ifaceMgrRpcService.getInterfaceEgressActions(ifName);
-        AtomicInteger counter = new AtomicInteger(actionCounter);
-        return actionInfos.stream().map(v -> v.buildAction(counter.getAndIncrement())).collect(Collectors.toList());
+    public static List<Action> getEgressActionsForInterface(IInterfaceManager ifaceMgrRpcService,
+                                                            ItmRpcService itmRpcService, String ifName,
+                                                            int actionCounter, boolean isTunnelInterface) {
+        if (isTunnelInterface && ifaceMgrRpcService.isItmDirectTunnelsEnabled()) {
+            try {
+                RpcResult result = itmRpcService.getEgressActionsForTunnel(new GetEgressActionsForTunnelInputBuilder()
+                        .setIntfName(ifName).build()).get();
+                Map<ActionKey, Action> listActions = new HashMap<ActionKey, Action>();
+                if (!result.isSuccessful()) {
+                    LOG.error("getEgressActionsForInterface: RPC Call to Get egress actions for interface {} "
+                            + "returned with Errors {}", ifName, result.getErrors());
+                } else {
+                    listActions = ((GetEgressActionsForTunnelOutput) result.getResult()).getAction();
+                }
+                return new ArrayList<Action>(listActions.values());
+            } catch (InterruptedException | ExecutionException e) {
+                LOG.error("getEgressActionsForInterface: Exception when egress actions for interface {}", ifName, e);
+            }
+        } else {
+            List<ActionInfo> actionInfos = ifaceMgrRpcService.getInterfaceEgressActions(ifName);
+            AtomicInteger counter = new AtomicInteger(actionCounter);
+            return actionInfos.stream().map(v -> v.buildAction(counter.getAndIncrement())).collect(Collectors.toList());
+        }
+        return Collections.emptyList();
     }
 
     /**
@@ -466,7 +410,7 @@ public final class ArpResponderUtil {
             RpcResult<AllocateIdOutput> rpcResult = result.get();
             if (rpcResult.isSuccessful()) {
                 LOG.trace("Retrieved Group Id is {}", rpcResult.getResult().getIdValue());
-                return rpcResult.getResult().getIdValue();
+                return rpcResult.getResult().getIdValue().toJava();
             } else {
                 LOG.warn("RPC Call to Allocate Id returned with Errors {}", rpcResult.getErrors());
             }