Policy classifier route group installation 24/53524/16
authorTali <tali.ben-meir@hpe.com>
Thu, 16 Mar 2017 12:53:03 +0000 (14:53 +0200)
committerAlon Kochba <alonko@hpe.com>
Thu, 30 Mar 2017 14:54:03 +0000 (14:54 +0000)
this patch depends on
https://git.opendaylight.org/gerrit/#/c/53049/

Change-Id: Id7e8391722b3e3825b7e11ea04e126532f9b8e19
Signed-off-by: Tali <tali.ben-meir@hpe.com>
vpnservice/policyservice/api/src/main/yang/policy-service.yang
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/PolicyIdManager.java
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/PolicyRouteGroupProgrammer.java [new file with mode: 0644]
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/PolicyServiceConstants.java
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/listeners/PolicyProfileChangeListener.java
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/listeners/TunnelStateChangeListener.java
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/listeners/UnderlayNetworkDpnListener.java
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/util/PolicyServiceFlowUtil.java
vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/util/PolicyServiceUtil.java
vpnservice/policyservice/impl/src/main/resources/org/opendaylight/blueprint/policyservice.xml

index 7d0c8fdb6ea4f14c49b7b4907199abacf350b808..95daa4d0a2cd07a0185d437aef16cd4772262076 100644 (file)
@@ -100,6 +100,10 @@ module policy-service {
                     leaf interface-name {
                         type string;
                     }
+
+                    leaf remote-dp-id {
+                        type uint64;
+                    }
                 }
             }
 
index 4620c33a046cc1c9f78a07f37960c67548be4dc8..bde68d62f6c0d0834637317085ab878bc4799b8c 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.netvirt.policyservice;
 
+import java.math.BigInteger;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
@@ -45,14 +46,41 @@ public class PolicyIdManager {
     @PostConstruct
     public void init() {
         LOG.info("init");
-        createIdPool();
+        createIdPools();
     }
 
-    private void createIdPool() {
-        CreateIdPoolInput createPoolInput = new CreateIdPoolInputBuilder()
-                .setPoolName(PolicyServiceConstants.POLICY_CLASSIFIER_POOL_NAME)
-                .setLow(PolicyServiceConstants.POLICY_CLASSIFIER_LOW_ID)
-                .setHigh(PolicyServiceConstants.POLICY_CLASSIFIER_HIGH_ID).build();
+    public long getPolicyClassifierId(String policyClassifierName) {
+        return allocateId(policyClassifierName, PolicyServiceConstants.POLICY_CLASSIFIER_POOL_NAME);
+    }
+
+    public void releasePolicyClassifierId(String policyClassifierName) {
+        releaseId(policyClassifierName, PolicyServiceConstants.POLICY_CLASSIFIER_POOL_NAME);
+    }
+
+    public long getPolicyClassifierGroupId(String policyClassifierName, BigInteger remoteDpId) {
+        return allocateId(getPolicyClassifierGroupKey(policyClassifierName, remoteDpId),
+                PolicyServiceConstants.POLICY_GROUP_POOL_NAME);
+    }
+
+    public void releasePolicyClassifierGroupId(String policyClassifierName, BigInteger remoteDpId) {
+        releaseId(getPolicyClassifierGroupKey(policyClassifierName, remoteDpId),
+                PolicyServiceConstants.POLICY_GROUP_POOL_NAME);
+    }
+
+    public static String getPolicyClassifierGroupKey(String policyClassifier, BigInteger remoteDpId) {
+        return policyClassifier + '-' + remoteDpId;
+    }
+
+    private void createIdPools() {
+        createIdPool(PolicyServiceConstants.POLICY_CLASSIFIER_POOL_NAME,
+                PolicyServiceConstants.POLICY_CLASSIFIER_LOW_ID, PolicyServiceConstants.POLICY_CLASSIFIER_HIGH_ID);
+        createIdPool(PolicyServiceConstants.POLICY_GROUP_POOL_NAME, PolicyServiceConstants.POLICY_GROUP_LOW_ID,
+                PolicyServiceConstants.POLICY_GROUP_HIGH_ID);
+    }
+
+    private void createIdPool(String poolName, long lowId, long highId) {
+        CreateIdPoolInput createPoolInput = new CreateIdPoolInputBuilder().setPoolName(poolName).setLow(lowId)
+                .setHigh(highId).build();
 
         try {
             Future<RpcResult<Void>> result = idManager.createIdPool(createPoolInput);
@@ -64,32 +92,29 @@ public class PolicyIdManager {
         }
     }
 
-    public long getPolicyClassifierId(String policyClassifierName) {
-        AllocateIdInput getIdInput = new AllocateIdInputBuilder()
-                .setPoolName(PolicyServiceConstants.POLICY_CLASSIFIER_POOL_NAME).setIdKey(policyClassifierName).build();
+    private long allocateId(String key, String poolName) {
+        AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(key).build();
         try {
             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
             RpcResult<AllocateIdOutput> rpcResult = result.get();
             return rpcResult.getResult().getIdValue();
         } catch (InterruptedException | ExecutionException e) {
-            LOG.warn("Exception thrown while allocating id for key {}", policyClassifierName);
+            LOG.warn("Exception thrown while allocating id for key {}", key);
         }
 
         return PolicyServiceConstants.INVALID_ID;
     }
 
-    public void releasePolicyClassifierId(String policyClassifierName) {
-        ReleaseIdInput idInput = new ReleaseIdInputBuilder()
-                .setPoolName(PolicyServiceConstants.POLICY_CLASSIFIER_POOL_NAME).setIdKey(policyClassifierName).build();
+    private void releaseId(String key, String poolName) {
+        ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(key).build();
         try {
             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
             RpcResult<Void> rpcResult = result.get();
             if (!rpcResult.isSuccessful()) {
-                LOG.warn("RPC Call to release {} returned with Errors {}", policyClassifierName, rpcResult.getErrors());
+                LOG.warn("RPC Call to release {} returned with Errors {}", key, rpcResult.getErrors());
             }
         } catch (InterruptedException | ExecutionException e) {
-            LOG.warn("Exception thrown while releasing id for key {}", policyClassifierName);
+            LOG.warn("Exception thrown while releasing id for key {}", key);
         }
     }
-
 }
diff --git a/vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/PolicyRouteGroupProgrammer.java b/vpnservice/policyservice/impl/src/main/java/org/opendaylight/netvirt/policyservice/PolicyRouteGroupProgrammer.java
new file mode 100644 (file)
index 0000000..b67c0a1
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2017 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.netvirt.policyservice;
+
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.netvirt.policyservice.util.PolicyServiceFlowUtil;
+import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.dpn.to._interface.TunnelInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Program policy classifier fast-failover groups per remote DPN.<br>
+ * Group id is allocated for combination of policy classifier and DPN id.<br>
+ * The group buckets are built based on the underlay networks defined for the
+ * policy classifier.<br>
+ * Each bucket in the group contains the tunnel egress actions for the actual
+ * tunnel interface associated with the underlay network.
+ *
+ */
+@Singleton
+public class PolicyRouteGroupProgrammer {
+    private static final Logger LOG = LoggerFactory.getLogger(PolicyRouteGroupProgrammer.class);
+
+    private final DataBroker dataBroker;
+    private final PolicyIdManager policyIdManager;
+    private final PolicyServiceUtil policyServiceUtil;
+    private final PolicyServiceFlowUtil policyServiceFlowUtil;
+    private final DataStoreJobCoordinator coordinator;
+
+    @Inject
+    public PolicyRouteGroupProgrammer(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
+            final PolicyServiceUtil policyServiceUtil, final PolicyServiceFlowUtil policyServiceFlowUtil) {
+        this.dataBroker = dataBroker;
+        this.policyIdManager = policyIdManager;
+        this.policyServiceUtil = policyServiceUtil;
+        this.policyServiceFlowUtil = policyServiceFlowUtil;
+        this.coordinator = DataStoreJobCoordinator.getInstance();
+    }
+
+    public void programPolicyClassifierGroups(String policyClassifier, List<BigInteger> localDpIds,
+            List<BigInteger> remoteDpIds, int addOrRemove) {
+        if (remoteDpIds == null || remoteDpIds.isEmpty()) {
+            LOG.debug("No remote DPNs found for policy classifier {}", policyClassifier);
+            return;
+        }
+
+        coordinator.enqueueJob(policyClassifier, () -> {
+            WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+            remoteDpIds.forEach(remoteDpId -> {
+                programPolicyClassifierGroups(policyClassifier, localDpIds, remoteDpId, tx, addOrRemove);
+            });
+            return Collections.singletonList(tx.submit());
+        });
+    }
+
+    public void programPolicyClassifierGroups(String policyClassifier, BigInteger dpId,
+            List<TunnelInterface> tunnelInterfaces, int addOrRemove) {
+        if (tunnelInterfaces == null) {
+            LOG.debug("No tunnel interfaces found for policy classifier {} DPN {}", policyClassifier, dpId);
+            return;
+
+        }
+        coordinator.enqueueJob(policyClassifier, () -> {
+            WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+            tunnelInterfaces.forEach(tunnelInterface -> {
+                BigInteger remoteDpId = tunnelInterface.getRemoteDpId();
+                programPolicyClassifierGroups(policyClassifier, Collections.singletonList(dpId), remoteDpId, tx,
+                        addOrRemove);
+            });
+            return Collections.singletonList(tx.submit());
+        });
+    }
+
+    private void programPolicyClassifierGroups(String policyClassifier, List<BigInteger> localDpIds,
+            BigInteger remoteDpId, WriteTransaction tx, int addOrRemove) {
+        long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifier, remoteDpId);
+        if (groupId == PolicyServiceConstants.INVALID_ID) {
+            LOG.error("Failed to get group id for policy classifier {}", policyClassifier);
+            return;
+        }
+
+        if (localDpIds == null || localDpIds.isEmpty()) {
+            LOG.debug("No DPNs found for policy classifier {}", policyClassifier);
+            return;
+        }
+
+        String groupName = PolicyIdManager.getPolicyClassifierGroupKey(policyClassifier, remoteDpId);
+        localDpIds.forEach(srcDpId -> {
+            if (!remoteDpId.equals(srcDpId)) {
+                policyServiceFlowUtil.updateGroupToTx(srcDpId, groupId, groupName, GroupTypes.GroupFf, addOrRemove, tx);
+            }
+        });
+    }
+
+    public void programPolicyClassifierGroupBuckets(String policyClassifier, List<String> underlayNetworks,
+            int addOrRemove) {
+        if (underlayNetworks == null) {
+            return;
+        }
+
+        coordinator.enqueueJob(policyClassifier, () -> {
+            WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+
+            for (int idx = 0; idx < underlayNetworks.size(); idx++) {
+                final int bucketId = idx;
+                String underlayNetwork = underlayNetworks.get(idx);
+                Optional.ofNullable(policyServiceUtil.getUnderlayNetworkDpnToInterfaces(underlayNetwork))
+                        .map(dpnToInterfaceList -> {
+                            dpnToInterfaceList.forEach(dpnToInterfaces -> {
+                                BigInteger dpId = dpnToInterfaces.getDpId();
+                                List<TunnelInterface> tunnelInterfaces = dpnToInterfaces.getTunnelInterface();
+                                programPolicyClassifierGroupBuckets(policyClassifier, tunnelInterfaces, dpId, bucketId,
+                                        addOrRemove, tx);
+                            });
+                            return dpnToInterfaceList;
+                        }).orElseGet(() -> {
+                            LOG.debug("No DpnToInterface found for underlay network {}", underlayNetwork);
+                            return null;
+                        });
+            }
+            return Collections.singletonList(tx.submit());
+        });
+    }
+
+    public void programPolicyClassifierGroupBuckets(String policyClassifier, List<TunnelInterface> tunnelInterfaces,
+            BigInteger dpId, int bucketId, int addOrRemove) {
+        coordinator.enqueueJob(policyClassifier, () -> {
+            WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+            programPolicyClassifierGroupBuckets(policyClassifier, tunnelInterfaces, dpId, bucketId, addOrRemove, tx);
+            return Collections.singletonList(tx.submit());
+        });
+    }
+
+    private void programPolicyClassifierGroupBuckets(String policyClassifier, List<TunnelInterface> tunnelInterfaces,
+            BigInteger dpId, int bucketId, int addOrRemove, WriteTransaction tx) {
+        if (tunnelInterfaces == null) {
+            LOG.debug("No tunnel interfaces found for policy classifier {} DPN {}", policyClassifier, dpId);
+            return;
+        }
+
+        tunnelInterfaces.forEach(tunnelInterface -> {
+            String interfaceName = tunnelInterface.getInterfaceName();
+            BigInteger remoteDpId = tunnelInterface.getRemoteDpId();
+            long groupId = policyIdManager.getPolicyClassifierGroupId(policyClassifier, remoteDpId);
+            policyServiceFlowUtil.updateInterfaceBucketToTx(dpId, groupId, bucketId, interfaceName, addOrRemove, tx);
+        });
+    }
+}
index cb00a9a9e4d5a718f84afdeb71fbdd41e133ac50..859f82ad2188db4bb1b0fd2fc8859cd359ada142 100644 (file)
@@ -13,6 +13,9 @@ public class PolicyServiceConstants {
     public static final String POLICY_CLASSIFIER_POOL_NAME = "policyClassifierPool";
     public static final Long POLICY_CLASSIFIER_LOW_ID = 1L;
     public static final Long POLICY_CLASSIFIER_HIGH_ID = 30000L;
+    public static final String POLICY_GROUP_POOL_NAME = "policyGroupPool";
+    public static final Long POLICY_GROUP_LOW_ID = 310000L;
+    public static final Long POLICY_GROUP_HIGH_ID = 320000L;
     public static final long INVALID_ID = 0;
     public static final int POLICY_FLOW_PRIOPITY = 42;
 }
index b637ebc73e70761adff05a675c179fe50caf3375..a4e907eb8641b8f623223ba3df2a0b072edc2d34 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.netvirt.policyservice.PolicyAceFlowProgrammer;
 import org.opendaylight.netvirt.policyservice.PolicyIdManager;
+import org.opendaylight.netvirt.policyservice.PolicyRouteGroupProgrammer;
 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.PolicyProfiles;
@@ -53,14 +54,17 @@ public class PolicyProfileChangeListener
     private final PolicyIdManager policyIdManager;
     private final PolicyServiceUtil policyServiceUtil;
     private final PolicyAceFlowProgrammer aceFlowProgrammer;
+    private final PolicyRouteGroupProgrammer routeGroupProgramer;
 
     @Inject
     public PolicyProfileChangeListener(final DataBroker dataBroker, final PolicyIdManager policyIdManager,
-            final PolicyServiceUtil policyServiceUtil, final PolicyAceFlowProgrammer aceFlowProgrammer) {
+            final PolicyServiceUtil policyServiceUtil, final PolicyAceFlowProgrammer aceFlowProgrammer,
+            final PolicyRouteGroupProgrammer routeGroupProgramer) {
         this.dataBroker = dataBroker;
         this.policyIdManager = policyIdManager;
         this.policyServiceUtil = policyServiceUtil;
         this.aceFlowProgrammer = aceFlowProgrammer;
+        this.routeGroupProgramer = routeGroupProgramer;
     }
 
     @Override
@@ -86,40 +90,60 @@ public class PolicyProfileChangeListener
         LOG.info("Policy profile {} removed", policyClassifier);
         List<String> underlayNetworks = PolicyServiceUtil
                 .getUnderlayNetworksFromPolicyRoutes(policyProfile.getPolicyRoute());
-        handlePolicyProfileUpdate(policyClassifier, underlayNetworks, false);
+        policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(underlayNetworks, policyClassifier, false);
+        List<BigInteger> dpnIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
+        List<BigInteger> remoteDpIds = policyServiceUtil.getUnderlayNetworksRemoteDpns(underlayNetworks);
+        routeGroupProgramer.programPolicyClassifierGroups(policyClassifier, dpnIds, remoteDpIds, NwConstants.DEL_FLOW);
+        updatePolicyAclRules(policyClassifier, underlayNetworks, NwConstants.DEL_FLOW);
         policyIdManager.releasePolicyClassifierId(policyClassifier);
-
+        releasePolicyClassifierGroupIds(policyClassifier, dpnIds);
     }
 
     @Override
     protected void update(InstanceIdentifier<PolicyProfile> key, PolicyProfile origPolicyProfile,
             PolicyProfile updatedPolicyProfile) {
-        LOG.info("Policy profile {} updated", updatedPolicyProfile.getPolicyClassifier());
         List<String> origUnderlayNetworks = PolicyServiceUtil
                 .getUnderlayNetworksFromPolicyRoutes(origPolicyProfile.getPolicyRoute());
         List<String> updatedUnderlayNetworks = PolicyServiceUtil
                 .getUnderlayNetworksFromPolicyRoutes(updatedPolicyProfile.getPolicyRoute());
-
         List<String> removedUnderlayNetworks = new ArrayList<>(origUnderlayNetworks);
         removedUnderlayNetworks.removeAll(updatedUnderlayNetworks);
-        policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(removedUnderlayNetworks,
-                origPolicyProfile.getPolicyClassifier(), false);
+        List<String> addedUnderlayNetworks = new ArrayList<>(updatedUnderlayNetworks);
+        addedUnderlayNetworks.removeAll(origUnderlayNetworks);
+
+        String policyClassifier = updatedPolicyProfile.getPolicyClassifier();
+        LOG.info("Policy profile {} updated", policyClassifier);
+        policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(removedUnderlayNetworks, policyClassifier, false);
+        policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(addedUnderlayNetworks, policyClassifier, true);
+
+        // rewrite all group buckets
+        routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, origUnderlayNetworks,
+                NwConstants.DEL_FLOW);
+        routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, updatedUnderlayNetworks,
+                NwConstants.ADD_FLOW);
 
         updatedUnderlayNetworks.removeAll(origUnderlayNetworks);
         policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(updatedUnderlayNetworks,
                 updatedPolicyProfile.getPolicyClassifier(), true);
+        updatePolicyAclRules(policyClassifier, updatedUnderlayNetworks, NwConstants.ADD_FLOW);
     }
 
     @Override
     protected void add(InstanceIdentifier<PolicyProfile> key, PolicyProfile policyProfile) {
-        LOG.info("Policy profile {} added", policyProfile.getPolicyClassifier());
+        String policyClassifier = policyProfile.getPolicyClassifier();
+        LOG.info("Policy profile {} added", policyClassifier);
         List<String> underlayNetworks = PolicyServiceUtil
                 .getUnderlayNetworksFromPolicyRoutes(policyProfile.getPolicyRoute());
-        handlePolicyProfileUpdate(policyProfile.getPolicyClassifier(), underlayNetworks, true);
+        policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(underlayNetworks, policyClassifier, true);
+        List<BigInteger> dpnIds = policyServiceUtil.getUnderlayNetworksDpns(underlayNetworks);
+        List<BigInteger> remoteDpIds = policyServiceUtil.getUnderlayNetworksRemoteDpns(underlayNetworks);
+        routeGroupProgramer.programPolicyClassifierGroups(policyClassifier, dpnIds, remoteDpIds, NwConstants.ADD_FLOW);
+        routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, underlayNetworks,
+                NwConstants.ADD_FLOW);
+        updatePolicyAclRules(policyClassifier, underlayNetworks, NwConstants.ADD_FLOW);
     }
 
-    private void handlePolicyProfileUpdate(String policyClassifier, List<String> underlayNetworks, boolean isAdded) {
-        policyServiceUtil.updatePolicyClassifierForUnderlayNetworks(underlayNetworks, policyClassifier, isAdded);
+    private void updatePolicyAclRules(String policyClassifier, List<String> underlayNetworks, int addOrRemove) {
         List<PolicyAclRule> aclRules = policyServiceUtil.getPolicyClassifierAclRules(policyClassifier);
         if (aclRules == null || aclRules.isEmpty()) {
             LOG.debug("No policy ACE rules found for policy classifier {}", policyClassifier);
@@ -139,7 +163,7 @@ public class PolicyProfileChangeListener
                             .getPolicyAce(aclRule.getAclName(), aceRule.getRuleName());
                     if (policyAceOpt.isPresent()) {
                         aceFlowProgrammer.programAceFlows(policyAceOpt.get(), policyClassifier, dpIds,
-                                isAdded ? NwConstants.ADD_FLOW : NwConstants.DEL_FLOW);
+                                addOrRemove);
                     }
                 });
                 return aceRules;
@@ -150,4 +174,9 @@ public class PolicyProfileChangeListener
         });
     }
 
+    private void releasePolicyClassifierGroupIds(String policyClassifier, List<BigInteger> dpnIds) {
+        dpnIds.forEach(dpnId -> {
+            policyIdManager.releasePolicyClassifierGroupId(policyClassifier, dpnId);
+        });
+    }
 }
index a98bdf0bd9b8ad89a77659d834c81da9c09f1b43..e0f3c7f71eeb7c859e17d9afd485315328eac530 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepInfoAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterface;
@@ -85,28 +86,30 @@ public class TunnelStateChangeListener
             return;
         }
 
-        BigInteger dpnId = getTunnelDpnId(tunnelState);
+        BigInteger srcDpId = getTepDpnId(tunnelState.getSrcInfo());
+        BigInteger dstDpId = getTepDpnId(tunnelState.getDstInfo());
         String tunnelInterfaceName = tunnelState.getTunnelInterfaceName();
-        if (BigInteger.ZERO.equals(dpnId)) {
+        if (BigInteger.ZERO.equals(srcDpId) || BigInteger.ZERO.equals(dstDpId)) {
             LOG.warn("No valid DPN found for tunnel {}", tunnelInterfaceName);
             return;
         }
 
         IpAddress tunnelIp = getTunnelIp(tunnelState);
         if (tunnelIp == null) {
-            LOG.warn("No tunnel ip found for tunnel {} DPN {}", tunnelInterfaceName, dpnId);
+            LOG.warn("No tunnel ip found for tunnel {} DPN {}", tunnelInterfaceName, srcDpId);
             return;
         }
 
-        String underlayNetwork = policyServiceUtil.getTunnelUnderlayNetwork(dpnId, tunnelIp);
+        String underlayNetwork = policyServiceUtil.getTunnelUnderlayNetwork(srcDpId, tunnelIp);
         if (underlayNetwork == null) {
-            LOG.debug("No underlay networks defined for tunnel {} DPN {}", tunnelInterfaceName, dpnId);
+            LOG.debug("No underlay networks defined for tunnel {} DPN {}", tunnelInterfaceName, srcDpId);
             return;
         }
 
-        LOG.info("Handle tunnel state update for interface {} on DPN {} underlay network", tunnelInterfaceName, dpnId,
+        LOG.info("Handle tunnel state update for interface {} on DPN {} underlay network", tunnelInterfaceName, srcDpId,
                 underlayNetwork);
-        policyServiceUtil.updateTunnelInterfaceForUnderlayNetwork(underlayNetwork, dpnId, tunnelInterfaceName, isAdded);
+        policyServiceUtil.updateTunnelInterfaceForUnderlayNetwork(underlayNetwork, srcDpId, dstDpId,
+                tunnelInterfaceName, isAdded);
     }
 
     private static boolean isVxlanTunnel(StateTunnelList tunnelState) {
@@ -114,9 +117,9 @@ public class TunnelStateChangeListener
                 && tunnelState.getTransportType().isAssignableFrom(TunnelTypeVxlan.class);
     }
 
-    private static BigInteger getTunnelDpnId(StateTunnelList tunnelState) {
-        if (tunnelState.getSrcInfo() != null && tunnelState.getSrcInfo().getTepDeviceId() != null) {
-            return new BigInteger(tunnelState.getSrcInfo().getTepDeviceId());
+    private static BigInteger getTepDpnId(TepInfoAttributes tepInfoAttributes) {
+        if (tepInfoAttributes != null && tepInfoAttributes.getTepDeviceId() != null) {
+            return new BigInteger(tepInfoAttributes.getTepDeviceId());
         }
 
         return BigInteger.ZERO;
index ffcb8adbc3864e2f54813dc538fb662edba9755d..68bae3140082051c4fa943dc1cdbae628095c39b 100644 (file)
@@ -8,7 +8,10 @@
 
 package org.opendaylight.netvirt.policyservice.listeners;
 
+
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
@@ -21,12 +24,14 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.netvirt.policyservice.PolicyAceFlowProgrammer;
+import org.opendaylight.netvirt.policyservice.PolicyRouteGroupProgrammer;
 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.UnderlayNetworks;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.UnderlayNetwork;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.PolicyProfile;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.dpn.to._interface.TunnelInterface;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,13 +51,15 @@ public class UnderlayNetworkDpnListener
     private final DataBroker dataBroker;
     private final PolicyServiceUtil policyServiceUtil;
     private final PolicyAceFlowProgrammer aceFlowProgrammer;
+    private final PolicyRouteGroupProgrammer routeGroupProgramer;
 
     @Inject
     public UnderlayNetworkDpnListener(final DataBroker dataBroker, final PolicyServiceUtil policyServiceUtil,
-            final PolicyAceFlowProgrammer aceFlowProgrammer) {
+            final PolicyAceFlowProgrammer aceFlowProgrammer, final PolicyRouteGroupProgrammer routeGroupProgramer) {
         this.dataBroker = dataBroker;
         this.policyServiceUtil = policyServiceUtil;
         this.aceFlowProgrammer = aceFlowProgrammer;
+        this.routeGroupProgramer = routeGroupProgramer;
     }
 
     @Override
@@ -75,35 +82,102 @@ public class UnderlayNetworkDpnListener
 
     @Override
     protected void remove(InstanceIdentifier<DpnToInterface> key, DpnToInterface dpnToInterface) {
+        String underlayNetwork = key.firstKeyOf(UnderlayNetwork.class).getNetworkName();
+        BigInteger dpId = dpnToInterface.getDpId();
+        List<TunnelInterface> tunnelInterfaces = dpnToInterface.getTunnelInterface();
+        LOG.info("DPN {} removed from underlay network {} with tunnels {}", dpId, underlayNetwork, tunnelInterfaces);
+        List<PolicyProfile> profiles = policyServiceUtil.getUnderlayNetworkPolicyProfiles(underlayNetwork);
+        if (profiles == null || profiles.isEmpty()) {
+            LOG.debug("No policy profiles found for underlay network {}", underlayNetwork);
+            return;
+        }
+
+        populatePolicyGroupsToDpn(underlayNetwork, profiles, tunnelInterfaces, dpId, NwConstants.DEL_FLOW);
+        populatePolicyAclRulesToDpn(underlayNetwork, dpId, profiles, NwConstants.DEL_FLOW);
     }
 
     @Override
     protected void update(InstanceIdentifier<DpnToInterface> key, DpnToInterface origDpnToInterface,
             DpnToInterface updatedDpnToInterface) {
+        String underlayNetwork = key.firstKeyOf(UnderlayNetwork.class).getNetworkName();
+        BigInteger dpId = updatedDpnToInterface.getDpId();
+        LOG.info("DPN {} updated to underlay network {} with tunnels {}", dpId, underlayNetwork,
+                updatedDpnToInterface.getTunnelInterface());
+        List<PolicyProfile> profiles = policyServiceUtil.getUnderlayNetworkPolicyProfiles(underlayNetwork);
+        if (profiles == null || profiles.isEmpty()) {
+            LOG.debug("No policy profiles found for underlay network {}", underlayNetwork);
+            return;
+        }
+
+        List<TunnelInterface> origTunnelInterfaces = Optional.ofNullable(origDpnToInterface.getTunnelInterface())
+                .orElse(Collections.emptyList());
+        List<TunnelInterface> updatedTunnelInterfaces = Optional.ofNullable(updatedDpnToInterface.getTunnelInterface())
+                .orElse(Collections.emptyList());
+        List<TunnelInterface> removedTunnelInterfaces = new ArrayList<>(origTunnelInterfaces);
+        removedTunnelInterfaces.removeAll(updatedTunnelInterfaces);
+        List<TunnelInterface> addedTunnelInterfaces = new ArrayList<>(updatedTunnelInterfaces);
+        addedTunnelInterfaces.removeAll(origTunnelInterfaces);
+
+        populatePolicyRoutesToDpn(underlayNetwork, profiles, removedTunnelInterfaces, dpId, NwConstants.DEL_FLOW);
+        populatePolicyRoutesToDpn(underlayNetwork, profiles, addedTunnelInterfaces, dpId, NwConstants.ADD_FLOW);
     }
 
     @Override
     protected void add(InstanceIdentifier<DpnToInterface> key, DpnToInterface dpnToInterface) {
         String underlayNetwork = key.firstKeyOf(UnderlayNetwork.class).getNetworkName();
         BigInteger dpId = dpnToInterface.getDpId();
-        LOG.info("DPN {} added to underlay network {}", dpId, underlayNetwork);
-        populatePolicyRulesToDpn(underlayNetwork, dpId);
-
-    }
-
-    private void populatePolicyRulesToDpn(String underlayNetwork, BigInteger dpId) {
+        List<TunnelInterface> tunnelInterfaces = dpnToInterface.getTunnelInterface();
+        LOG.info("DPN {} added to underlay network {} with tunnels {}", dpId, underlayNetwork, tunnelInterfaces);
         List<PolicyProfile> profiles = policyServiceUtil.getUnderlayNetworkPolicyProfiles(underlayNetwork);
         if (profiles == null || profiles.isEmpty()) {
             LOG.debug("No policy profiles found for underlay network {}", underlayNetwork);
             return;
         }
 
+        populatePolicyGroupsToDpn(underlayNetwork, profiles, tunnelInterfaces, dpId, NwConstants.ADD_FLOW);
+        populatePolicyRoutesToDpn(underlayNetwork, profiles, tunnelInterfaces, dpId, NwConstants.ADD_FLOW);
+        populatePolicyAclRulesToDpn(underlayNetwork, dpId, profiles, NwConstants.ADD_FLOW);
+    }
+
+    private void populatePolicyGroupsToDpn(String underlayNetwork, List<PolicyProfile> profiles,
+            List<TunnelInterface> tunnelInterfaces, BigInteger dpId, int addOrRemove) {
+        profiles.forEach(profile -> {
+            String policyClassifier = profile.getPolicyClassifier();
+            routeGroupProgramer.programPolicyClassifierGroups(policyClassifier, dpId, tunnelInterfaces, addOrRemove);
+        });
+    }
+
+    private void populatePolicyRoutesToDpn(String underlayNetwork, List<PolicyProfile> profiles,
+            List<TunnelInterface> tunnelInterfaces, BigInteger dpId, int addOrRemove) {
+        profiles.forEach(profile -> {
+            String policyClassifier = profile.getPolicyClassifier();
+            Optional.ofNullable(policyServiceUtil.getUnderlayNetworksForClassifier(policyClassifier))
+                    .map(underlayNetworks -> {
+                        int bucketId = underlayNetworks.indexOf(underlayNetwork);
+                        if (bucketId != -1) {
+                            routeGroupProgramer.programPolicyClassifierGroupBuckets(policyClassifier, tunnelInterfaces,
+                                    dpId, bucketId, addOrRemove);
+                        } else {
+                            LOG.warn("Policy classifier {} routes do not contain {}", policyClassifier,
+                                    underlayNetwork);
+                        }
+                        return underlayNetworks;
+                    }).orElseGet(() -> {
+                        LOG.warn("No underlay networks found for classifier {} while populating {} flows",
+                                policyClassifier, underlayNetwork);
+                        return null;
+                    });
+        });
+    }
+
+    private void populatePolicyAclRulesToDpn(String underlayNetwork, BigInteger dpId, List<PolicyProfile> profiles,
+            int addOrRemove) {
         profiles.forEach(profile -> {
             String policyClassifier = profile.getPolicyClassifier();
 
             Optional.ofNullable(policyServiceUtil.getPolicyClassifierAclRules(policyClassifier)).ifPresent(aclRules -> {
                 aclRules.forEach(aclRule -> {
-                    Optional.ofNullable(aclRule.getAceRule()).ifPresent(aceRules -> {
+                    Optional.ofNullable(aclRule.getAceRule()).map(aceRules -> {
                         aceRules.forEach(aceRule -> {
                             com.google.common.base.Optional<Ace> policyAceOpt = policyServiceUtil
                                     .getPolicyAce(aclRule.getAclName(), aceRule.getRuleName());
@@ -113,10 +187,13 @@ public class UnderlayNetworkDpnListener
                                 LOG.warn("Failed to get ACL {} rule {}", aclRule.getAclName(), aceRule.getRuleName());
                             }
                         });
+                        return aceRules;
+                    }).orElseGet(() -> {
+                        LOG.debug("No ACE rule found for policy ACL {}", aclRule.getAclName());
+                        return null;
                     });
                 });
             });
         });
     }
-
 }
index 1263e883cb1e249405caf41790a931602110b453..71ae152322334dbbf13cb2aac244687e2d60eadb 100644 (file)
@@ -10,13 +10,17 @@ package org.opendaylight.netvirt.policyservice.util;
 
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
 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.MatchInfoBase;
@@ -25,15 +29,23 @@ import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.netvirt.policyservice.PolicyServiceConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @Singleton
 public class PolicyServiceFlowUtil {
+    private static final Logger LOG = LoggerFactory.getLogger(PolicyServiceFlowUtil.class);
 
     private final IMdsalApiManager mdsalManager;
+    private final IInterfaceManager interfaceManager;
 
     @Inject
-    public PolicyServiceFlowUtil(final IMdsalApiManager mdsalManager) {
+    public PolicyServiceFlowUtil(final IMdsalApiManager mdsalManager, final IInterfaceManager interfaceManager) {
         this.mdsalManager = mdsalManager;
+        this.interfaceManager = interfaceManager;
     }
 
     public List<InstructionInfo> getPolicyClassifierInstructions(long policyClassifierId) {
@@ -55,4 +67,53 @@ public class PolicyServiceFlowUtil {
             mdsalManager.removeFlowToTx(flowEntity, tx);
         }
     }
+
+    public void updateGroupToTx(BigInteger dpId, long groupId, String groupName, GroupTypes groupType, int addOrRemove,
+            WriteTransaction tx) {
+        if (addOrRemove == NwConstants.ADD_FLOW && mdsalManager.groupExists(dpId, groupId)) {
+            LOG.trace("Group {} id {} already exists", groupName, groupId);
+            return;
+        }
+
+        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpId, groupId, groupName, groupType,
+                Collections.emptyList());
+        if (addOrRemove == NwConstants.ADD_FLOW) {
+            LOG.debug("Add group {} to DPN {}", groupId, dpId);
+            mdsalManager.addGroupToTx(groupEntity, tx);
+        } else {
+            LOG.debug("Remove group {} from DPN {}", groupId, dpId);
+            mdsalManager.removeGroupToTx(groupEntity, tx);
+        }
+    }
+
+    public void updateInterfaceBucketToTx(BigInteger dpId, long groupId, int bucketId, String interfaceName,
+            int addOrRemove, WriteTransaction tx) {
+        if (groupId == PolicyServiceConstants.INVALID_ID) {
+            LOG.error("No valid group id found for interface {} DPN {}", interfaceName, dpId);
+            return;
+        }
+
+        if (addOrRemove == NwConstants.DEL_FLOW) {
+            LOG.debug("Remove bucket for interface {} from group {} DPN {}", interfaceName, groupId, dpId);
+            mdsalManager.removeBucketToTx(dpId, groupId, bucketId, tx);
+            return;
+        }
+
+        List<ActionInfo> egressActions = interfaceManager.getInterfaceEgressActions(interfaceName);
+        if (egressActions == null || egressActions.isEmpty()) {
+            LOG.error("Failed to get egress actions for interface {} DPN {}", interfaceName, dpId);
+            return;
+        }
+
+        Long port = interfaceManager.getPortForInterface(interfaceName);
+        if (port == null) {
+            LOG.error("Failed to get port for interface {}", interfaceName);
+            return;
+        }
+
+        Bucket bucket = MDSALUtil.buildBucket(MDSALUtil.buildActions(egressActions), MDSALUtil.GROUP_WEIGHT, bucketId,
+                port, MDSALUtil.WATCH_GROUP);
+        LOG.debug("Add bucket for interface {} to group {} DPN {}", interfaceName, groupId, dpId);
+        mdsalManager.addBucketToTx(dpId, groupId, bucket, tx);
+    }
 }
index eb2a678193092c995b0c06735941704df1701723..845c3edcfddf8be8e56cc49a982c1ecd588849c1 100644 (file)
@@ -148,19 +148,22 @@ public class PolicyServiceUtil {
         }
     }
 
-    public void updateTunnelInterfaceForUnderlayNetwork(String underlayNetwork, BigInteger dpId, String tunnelInterface,
-            boolean isAdded) {
+    public void updateTunnelInterfaceForUnderlayNetwork(String underlayNetwork, BigInteger srcDpId, BigInteger dstDpId,
+            String tunnelInterfaceName, boolean isAdded) {
         coordinator.enqueueJob(underlayNetwork, () -> {
-            InstanceIdentifier<TunnelInterface> identifier = getUnderlyNetworkTunnelIdentifier(underlayNetwork, dpId,
-                    tunnelInterface);
+            InstanceIdentifier<TunnelInterface> identifier = getUnderlyNetworkTunnelIdentifier(underlayNetwork, srcDpId,
+                    tunnelInterfaceName);
             WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
             if (isAdded) {
-                tx.merge(LogicalDatastoreType.OPERATIONAL, identifier,
-                        new TunnelInterfaceBuilder().setInterfaceName(tunnelInterface).build(), true);
-                LOG.info("Add tunnel {} on DPN {} to underlay network {}", tunnelInterface, dpId, underlayNetwork);
+                TunnelInterface tunnelInterface = new TunnelInterfaceBuilder().setInterfaceName(tunnelInterfaceName)
+                        .setRemoteDpId(dstDpId).build();
+                tx.merge(LogicalDatastoreType.OPERATIONAL, identifier, tunnelInterface, true);
+                LOG.info("Add tunnel {} on DPN {} to underlay network {}", tunnelInterfaceName, srcDpId,
+                        underlayNetwork);
             } else {
                 tx.delete(LogicalDatastoreType.OPERATIONAL, identifier);
-                LOG.info("Remove tunnel {} from DPN {} on underlay network {}", tunnelInterface, dpId, underlayNetwork);
+                LOG.info("Remove tunnel {} from DPN {} on underlay network {}", tunnelInterfaceName, srcDpId,
+                        underlayNetwork);
             }
             return Collections.singletonList(tx.submit());
         });
@@ -220,6 +223,15 @@ public class PolicyServiceUtil {
                 .collect(Collectors.toList());
     }
 
+    public List<BigInteger> getUnderlayNetworksRemoteDpns(List<String> underlayNetworks) {
+        if (underlayNetworks == null) {
+            return Collections.emptyList();
+        }
+
+        return underlayNetworks.stream().map(t -> getUnderlayNetworkRemoteDpns(t)).flatMap(t -> t.stream()).distinct()
+                .collect(Collectors.toList());
+    }
+
     public String getTunnelUnderlayNetwork(BigInteger dpId, IpAddress tunnelIp) {
         Node ovsdbNode = bridgeManager.getBridgeNode(dpId);
         if (ovsdbNode == null) {
@@ -239,6 +251,25 @@ public class PolicyServiceUtil {
         return dpnToInterfaces.stream().map(t -> t.getDpId()).collect(Collectors.toList());
     }
 
+    public static List<BigInteger> getRemoteDpnsFromDpnToInterfaces(List<DpnToInterface> dpnToInterfaces) {
+        if (dpnToInterfaces == null) {
+            return Collections.emptyList();
+        }
+
+        return dpnToInterfaces.stream().map(dpnToInterface -> getRemoteDpnsFromDpnToInterface(dpnToInterface))
+                .flatMap(t -> t.stream()).distinct().collect(Collectors.toList());
+    }
+
+    public static List<BigInteger> getRemoteDpnsFromDpnToInterface(DpnToInterface dpnToInterface) {
+        List<TunnelInterface> tunnelInterfaces = dpnToInterface.getTunnelInterface();
+        if (tunnelInterfaces == null) {
+            return Collections.emptyList();
+        }
+
+        return tunnelInterfaces.stream().map(tunnelInterface -> tunnelInterface.getRemoteDpId())
+                .collect(Collectors.toList());
+    }
+
     public static List<String> getUnderlayNetworksFromPolicyRoutes(List<PolicyRoute> policyRoutes) {
         if (policyRoutes == null) {
             return Collections.emptyList();
@@ -253,13 +284,13 @@ public class PolicyServiceUtil {
         return aclType != null && aclType.isAssignableFrom(PolicyAcl.class);
     }
 
-    private List<BigInteger> getUnderlayNetworkDpns(String underlayNetwork) {
-        InstanceIdentifier<UnderlayNetwork> identifier = getUnderlyNetworkIdentifier(underlayNetwork);
+    public List<DpnToInterface> getUnderlayNetworkDpnToInterfaces(String underlayNetwork) {
+        InstanceIdentifier<UnderlayNetwork> identifier = InstanceIdentifier.create(UnderlayNetworks.class)
+                .child(UnderlayNetwork.class, new UnderlayNetworkKey(underlayNetwork));
         try {
             Optional<UnderlayNetwork> optUnderlayNetwork = SingleTransactionDataBroker.syncReadOptional(dataBroker,
                     LogicalDatastoreType.OPERATIONAL, identifier);
-            return optUnderlayNetwork.isPresent()
-                    ? getDpnsFromDpnToInterfaces(optUnderlayNetwork.get().getDpnToInterface())
+            return optUnderlayNetwork.isPresent() ? optUnderlayNetwork.get().getDpnToInterface()
                     : Collections.emptyList();
         } catch (ReadFailedException e) {
             LOG.warn("Failed to get DPNs for underlay network {}", underlayNetwork);
@@ -309,4 +340,12 @@ public class PolicyServiceUtil {
                         .netvirt.policy.rev170207.underlay.networks.underlay.network
                         .PolicyProfileKey(policyClassifier));
     }
+
+    public List<BigInteger> getUnderlayNetworkDpns(String underlayNetwork) {
+        return getDpnsFromDpnToInterfaces(getUnderlayNetworkDpnToInterfaces(underlayNetwork));
+    }
+
+    public List<BigInteger> getUnderlayNetworkRemoteDpns(String underlayNetwork) {
+        return getRemoteDpnsFromDpnToInterfaces(getUnderlayNetworkDpnToInterfaces(underlayNetwork));
+    }
 }
index e4b15665db957ae3724dae57f2f7ffbb5195c994..d6256a65d898209335cd8ff2e0f1c406589d98de 100644 (file)
@@ -8,6 +8,8 @@
     interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" />
   <reference id="iMdsalApiManager"
     interface="org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager" />
+  <reference id="iInterfaceManager"
+    interface="org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager" />
   <reference id="iAclServiceUtil"
     interface="org.opendaylight.netvirt.aclservice.api.utils.IAclServiceUtil" />
   <reference id="iElanBridgeManager"