c8177d7745eaec773808da1e167a6f4d39c83f27
[netvirt.git] / vpnservice / policyservice / impl / src / main / java / org / opendaylight / netvirt / policyservice / util / PolicyServiceUtil.java
1 /*
2  * Copyright (c) 2017 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.policyservice.util;
10
11 import com.google.common.base.Optional;
12
13 import java.math.BigInteger;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
19 import java.util.stream.Collectors;
20
21 import javax.inject.Inject;
22 import javax.inject.Singleton;
23
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
28 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
29 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
30 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
31 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
32 import org.opendaylight.netvirt.elanmanager.api.IElanBridgeManager;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AccessLists;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AclBase;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntries;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceKey;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Actions;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.PolicyAcl;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.PolicyProfiles;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.SetPolicyClassifier;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.UnderlayNetworks;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.PolicyProfile;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.PolicyProfileKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.PolicyAclRule;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.PolicyAclRuleKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.PolicyRoute;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.policy.acl.rule.AceRule;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.policy.acl.rule.AceRuleBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.policy.acl.rule.AceRuleKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile.policy.route.route.BasicRoute;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.UnderlayNetwork;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.UnderlayNetworkKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterface;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterfaceKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.PolicyProfileBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.dpn.to._interface.TunnelInterface;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.dpn.to._interface.TunnelInterfaceBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.dpn.to._interface.TunnelInterfaceKey;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
72 import org.opendaylight.yangtools.yang.common.RpcResult;
73 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory;
75
76 @Singleton
77 public class PolicyServiceUtil {
78     private static final Logger LOG = LoggerFactory.getLogger(PolicyServiceUtil.class);
79
80     private static final String LOCAL_IPS = "local_ips";
81
82     private final DataBroker dataBroker;
83     private final IElanBridgeManager bridgeManager;
84     private final ItmRpcService itmRpcService;
85     private final IInterfaceManager interfaceManager;
86     private final DataStoreJobCoordinator coordinator;
87
88     @Inject
89     public PolicyServiceUtil(final DataBroker dataBroker, final IElanBridgeManager bridgeManager,
90             final ItmRpcService itmRpcService, final IInterfaceManager interfaceManager) {
91         this.dataBroker = dataBroker;
92         this.bridgeManager = bridgeManager;
93         this.itmRpcService = itmRpcService;
94         this.interfaceManager = interfaceManager;
95         this.coordinator = DataStoreJobCoordinator.getInstance();
96     }
97
98     public Optional<String> getAcePolicyClassifier(Ace ace) {
99         Actions actions = ace.getActions();
100         SetPolicyClassifier setPolicyClassifier = actions.getAugmentation(SetPolicyClassifier.class);
101         if (setPolicyClassifier == null) {
102             LOG.warn("No valid policy action found for ACE rule {}", ace.getRuleName());
103             return Optional.absent();
104         }
105
106         Class<? extends DirectionBase> direction;
107         try {
108             direction = setPolicyClassifier.getDirection();
109         } catch (IllegalArgumentException e) {
110             LOG.warn("Failed to parse policy classifier direction");
111             return null;
112         }
113
114         if (direction == null || !direction.isAssignableFrom(DirectionEgress.class)) {
115             LOG.trace("Ignoring non egress policy ACE rule {}", ace.getRuleName());
116             return Optional.absent();
117         }
118
119         return Optional.of(setPolicyClassifier.getPolicyClassifier());
120     }
121
122     public Optional<Ace> getPolicyAce(String aclName, String ruleName) {
123         InstanceIdentifier<Ace> identifier = getAceIdentifier(aclName, ruleName);
124         try {
125             return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
126                     identifier);
127         } catch (ReadFailedException e) {
128             LOG.warn("Failed to get policy ACE rule {} for ACL {}", ruleName, aclName);
129             return Optional.absent();
130         }
131     }
132
133     public List<PolicyProfile> getAllPolicyProfiles() {
134         InstanceIdentifier<PolicyProfiles> identifier = InstanceIdentifier.create(PolicyProfiles.class);
135         try {
136             Optional<PolicyProfiles> optProfiles = SingleTransactionDataBroker.syncReadOptional(dataBroker,
137                     LogicalDatastoreType.CONFIGURATION, identifier);
138             return optProfiles.isPresent() ? optProfiles.get().getPolicyProfile() : Collections.emptyList();
139         } catch (ReadFailedException e) {
140             LOG.warn("Failed to get policy profiles");
141             return Collections.emptyList();
142         }
143     }
144
145     public List<String> getUnderlayNetworksForClassifier(String policyClassifier) {
146         InstanceIdentifier<PolicyProfile> identifier = getPolicyClassifierIdentifier(policyClassifier);
147         try {
148             Optional<PolicyProfile> optProfile = SingleTransactionDataBroker.syncReadOptional(dataBroker,
149                     LogicalDatastoreType.CONFIGURATION, identifier);
150             return optProfile.isPresent() ? getUnderlayNetworksFromPolicyRoutes(optProfile.get().getPolicyRoute())
151                     : Collections.emptyList();
152         } catch (ReadFailedException e) {
153             LOG.warn("Failed to get policy routes for classifier {}", policyClassifier);
154             return Collections.emptyList();
155         }
156     }
157
158     public List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay
159         .network.PolicyProfile> getUnderlayNetworkPolicyProfiles(String underlayNetwork) {
160         InstanceIdentifier<UnderlayNetwork> identifier = getUnderlyNetworkIdentifier(underlayNetwork);
161         try {
162             Optional<UnderlayNetwork> optUnderlayNet = SingleTransactionDataBroker.syncReadOptional(dataBroker,
163                     LogicalDatastoreType.OPERATIONAL, identifier);
164             return optUnderlayNet.isPresent() ? optUnderlayNet.get().getPolicyProfile() : Collections.emptyList();
165         } catch (ReadFailedException e) {
166             LOG.warn("Failed to get policy classifiers for underlay network {}", underlayNetwork);
167             return Collections.emptyList();
168         }
169     }
170
171     public List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.policy.profiles.policy.profile
172         .PolicyAclRule> getPolicyClassifierAclRules(String policyClassifier) {
173         InstanceIdentifier<PolicyProfile> identifier = getPolicyClassifierIdentifier(policyClassifier);
174         try {
175             Optional<PolicyProfile> optProfile = SingleTransactionDataBroker.syncReadOptional(dataBroker,
176                     LogicalDatastoreType.OPERATIONAL, identifier);
177             return optProfile.isPresent() ? optProfile.get().getPolicyAclRule() : Collections.emptyList();
178         } catch (ReadFailedException e) {
179             LOG.warn("Failed to get policy rules for policy classifier {}", policyClassifier);
180             return Collections.emptyList();
181         }
182     }
183
184     public void updateTunnelInterfaceForUnderlayNetwork(String underlayNetwork, BigInteger srcDpId, BigInteger dstDpId,
185             String tunnelInterfaceName, boolean isAdded) {
186         coordinator.enqueueJob(underlayNetwork, () -> {
187             InstanceIdentifier<TunnelInterface> identifier = getUnderlyNetworkTunnelIdentifier(underlayNetwork, srcDpId,
188                     tunnelInterfaceName);
189             WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
190             if (isAdded) {
191                 TunnelInterface tunnelInterface = new TunnelInterfaceBuilder().setInterfaceName(tunnelInterfaceName)
192                         .setRemoteDpId(dstDpId).build();
193                 tx.merge(LogicalDatastoreType.OPERATIONAL, identifier, tunnelInterface, true);
194                 LOG.info("Add tunnel {} on DPN {} to underlay network {}", tunnelInterfaceName, srcDpId,
195                         underlayNetwork);
196             } else {
197                 tx.delete(LogicalDatastoreType.OPERATIONAL, identifier);
198                 LOG.info("Remove tunnel {} from DPN {} on underlay network {}", tunnelInterfaceName, srcDpId,
199                         underlayNetwork);
200             }
201             return Collections.singletonList(tx.submit());
202         });
203     }
204
205     public void updatePolicyClassifierForUnderlayNetworks(List<String> underlayNetworks, String policyClassifier,
206             boolean isAdded) {
207         if (underlayNetworks == null || underlayNetworks.isEmpty()) {
208             LOG.debug("No underlay networks found for policy classifier {}", policyClassifier);
209         }
210
211         underlayNetworks.forEach(underlayNetwork -> {
212             coordinator.enqueueJob(underlayNetwork, () -> {
213                 WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
214                 InstanceIdentifier<
215                         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks
216                         .underlay.network.PolicyProfile> identifier = getUnderlayNetworkPolicyClassifierIdentifier(
217                                 policyClassifier, underlayNetwork);
218
219                 if (isAdded) {
220                     tx.merge(LogicalDatastoreType.OPERATIONAL, identifier,
221                             new PolicyProfileBuilder().setPolicyClassifier(policyClassifier).build(), true);
222                     LOG.info("Add policy classifier {} to underlay network {}", policyClassifier, underlayNetwork);
223                 } else {
224                     tx.delete(LogicalDatastoreType.OPERATIONAL, identifier);
225                     LOG.info("Remove policy classifier {} from underlay network {}", policyClassifier, underlayNetwork);
226                 }
227                 return Collections.singletonList(tx.submit());
228             });
229         });
230     }
231
232     public void updateAclRuleForPolicyClassifier(String policyClassifier, String aclName, String ruleName,
233             boolean isAdded) {
234         coordinator.enqueueJob(policyClassifier, () -> {
235             InstanceIdentifier<
236                     AceRule> identifier = getPolicyClassifierAceIdentifier(policyClassifier, aclName, ruleName);
237             WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
238             if (isAdded) {
239                 tx.merge(LogicalDatastoreType.OPERATIONAL, identifier,
240                         new AceRuleBuilder().setRuleName(ruleName).build(), true);
241                 LOG.info("Add ACL {} rule {} to policy classifier {}", aclName, ruleName, policyClassifier);
242             } else {
243                 tx.delete(LogicalDatastoreType.OPERATIONAL, identifier);
244                 LOG.info("Remove ACL {} rule {} from policy classifier {}", aclName, ruleName, policyClassifier);
245             }
246             return Collections.singletonList(tx.submit());
247         });
248     }
249
250     public List<BigInteger> getUnderlayNetworksDpns(List<String> underlayNetworks) {
251         if (underlayNetworks == null) {
252             return Collections.emptyList();
253         }
254
255         return underlayNetworks.stream().flatMap(t -> getUnderlayNetworkDpns(t).stream()).distinct()
256                 .collect(Collectors.toList());
257     }
258
259     public List<BigInteger> getUnderlayNetworksRemoteDpns(List<String> underlayNetworks) {
260         if (underlayNetworks == null) {
261             return Collections.emptyList();
262         }
263
264         return underlayNetworks.stream().map(t -> getUnderlayNetworkRemoteDpns(t)).flatMap(t -> t.stream()).distinct()
265                 .collect(Collectors.toList());
266     }
267
268     public boolean underlayNetworkContainsDpn(String underlayNetwork, BigInteger dpId) {
269         return dpnToInterfacesContainsDpn(getUnderlayNetworkDpnToInterfaces(underlayNetwork), dpId);
270     }
271
272     public boolean underlayNetworkContainsRemoteDpn(String underlayNetwork, BigInteger dpId) {
273         return dpnToInterfacesContainsRemoteDpn(getUnderlayNetworkDpnToInterfaces(underlayNetwork), dpId);
274     }
275
276     public static boolean dpnToInterfacesContainsDpn(List<DpnToInterface> dpnToInterfaces, BigInteger dpId) {
277         if (dpnToInterfaces == null) {
278             return false;
279         }
280
281         return dpnToInterfaces.stream().filter(dpnToInterface -> dpnToInterface.getDpId().equals(dpId)).findFirst()
282                 .isPresent();
283     }
284
285     public static boolean dpnToInterfacesContainsRemoteDpn(List<DpnToInterface> dpnToInterfaces, BigInteger dpId) {
286         if (dpnToInterfaces == null) {
287             return false;
288         }
289
290         return dpnToInterfaces.stream().filter(dpnToInterface -> dpnToInterfaceContainsRemoteDpn(dpnToInterface, dpId))
291                 .findFirst().isPresent();
292     }
293
294     public static boolean dpnToInterfaceContainsRemoteDpn(DpnToInterface dpnToInterface, BigInteger dpId) {
295         List<TunnelInterface> tunnelInterfaces = dpnToInterface.getTunnelInterface();
296         if (tunnelInterfaces == null) {
297             return false;
298         }
299
300         return tunnelInterfaces.stream().filter(tunnelInterface -> tunnelInterface.getRemoteDpId().equals(dpId))
301                 .findFirst().isPresent();
302     }
303
304     public String getTunnelUnderlayNetwork(BigInteger dpId, IpAddress tunnelIp) {
305         Node ovsdbNode = bridgeManager.getBridgeNode(dpId);
306         if (ovsdbNode == null) {
307             LOG.error("Failed to get OVSDB node for DPN {}", dpId);
308             return null;
309         }
310
311         Map<String, String> localIpMap = bridgeManager.getOpenvswitchOtherConfigMap(ovsdbNode, LOCAL_IPS);
312         return localIpMap.get(String.valueOf(tunnelIp.getValue()));
313     }
314
315     public static List<BigInteger> getDpnsFromDpnToInterfaces(List<DpnToInterface> dpnToInterfaces) {
316         if (dpnToInterfaces == null) {
317             return Collections.emptyList();
318         }
319
320         return dpnToInterfaces.stream().map(t -> t.getDpId()).collect(Collectors.toList());
321     }
322
323     public static List<BigInteger> getRemoteDpnsFromDpnToInterfaces(List<DpnToInterface> dpnToInterfaces) {
324         if (dpnToInterfaces == null) {
325             return Collections.emptyList();
326         }
327
328         return dpnToInterfaces.stream().map(dpnToInterface -> getRemoteDpnsFromDpnToInterface(dpnToInterface))
329                 .flatMap(t -> t.stream()).distinct().collect(Collectors.toList());
330     }
331
332     public static List<BigInteger> getRemoteDpnsFromDpnToInterface(DpnToInterface dpnToInterface) {
333         List<TunnelInterface> tunnelInterfaces = dpnToInterface.getTunnelInterface();
334         if (tunnelInterfaces == null) {
335             return Collections.emptyList();
336         }
337
338         return tunnelInterfaces.stream().map(tunnelInterface -> tunnelInterface.getRemoteDpId())
339                 .collect(Collectors.toList());
340     }
341
342     public static List<String> getUnderlayNetworksFromPolicyRoutes(List<PolicyRoute> policyRoutes) {
343         if (policyRoutes == null) {
344             return Collections.emptyList();
345         }
346
347         return policyRoutes.stream().map(policyRoute -> policyRoute.getRoute())
348                 .filter(route -> route instanceof BasicRoute).map(route -> ((BasicRoute) route).getNetworkName())
349                 .collect(Collectors.toList());
350     }
351
352     public static boolean isPolicyAcl(Class<? extends AclBase> aclType) {
353         return aclType != null && aclType.isAssignableFrom(PolicyAcl.class);
354     }
355
356     public List<DpnToInterface> getUnderlayNetworkDpnToInterfaces(String underlayNetwork) {
357         InstanceIdentifier<UnderlayNetwork> identifier = InstanceIdentifier.create(UnderlayNetworks.class)
358                 .child(UnderlayNetwork.class, new UnderlayNetworkKey(underlayNetwork));
359         try {
360             Optional<UnderlayNetwork> optUnderlayNetwork = SingleTransactionDataBroker.syncReadOptional(dataBroker,
361                     LogicalDatastoreType.OPERATIONAL, identifier);
362             return optUnderlayNetwork.isPresent() ? optUnderlayNetwork.get().getDpnToInterface()
363                     : Collections.emptyList();
364         } catch (ReadFailedException e) {
365             LOG.warn("Failed to get DPNs for underlay network {}", underlayNetwork);
366             return Collections.emptyList();
367         }
368     }
369
370     private InstanceIdentifier<UnderlayNetwork> getUnderlyNetworkIdentifier(String underlayNetwork) {
371         return InstanceIdentifier.create(UnderlayNetworks.class).child(UnderlayNetwork.class,
372                 new UnderlayNetworkKey(underlayNetwork));
373     }
374
375     private InstanceIdentifier<TunnelInterface> getUnderlyNetworkTunnelIdentifier(String underlayNetwork,
376             BigInteger dpId, String tunnelInterface) {
377         return InstanceIdentifier.create(UnderlayNetworks.class)
378                 .child(UnderlayNetwork.class, new UnderlayNetworkKey(underlayNetwork))
379                 .child(DpnToInterface.class, new DpnToInterfaceKey(dpId))
380                 .child(TunnelInterface.class, new TunnelInterfaceKey(tunnelInterface));
381     }
382
383     private InstanceIdentifier<PolicyProfile> getPolicyClassifierIdentifier(String policyClassifier) {
384         return InstanceIdentifier.create(PolicyProfiles.class).child(PolicyProfile.class,
385                 new PolicyProfileKey(policyClassifier));
386     }
387
388     private InstanceIdentifier<Ace> getAceIdentifier(String aclName, String ruleName) {
389         return InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey(aclName, PolicyAcl.class))
390                 .child(AccessListEntries.class).child(Ace.class, new AceKey(ruleName));
391     }
392
393     private KeyedInstanceIdentifier<AceRule, AceRuleKey> getPolicyClassifierAceIdentifier(String policyClassifier,
394             String aclName, String ruleName) {
395         return InstanceIdentifier.create(PolicyProfiles.class)
396                 .child(PolicyProfile.class, new PolicyProfileKey(policyClassifier))
397                 .child(PolicyAclRule.class, new PolicyAclRuleKey(aclName))
398                 .child(AceRule.class, new AceRuleKey(ruleName));
399     }
400
401     private InstanceIdentifier<
402             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network
403                     .PolicyProfile> getUnderlayNetworkPolicyClassifierIdentifier(String policyClassifier,
404                             String underlayNetwork) {
405         return InstanceIdentifier.create(UnderlayNetworks.class)
406                 .child(UnderlayNetwork.class, new UnderlayNetworkKey(underlayNetwork))
407                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks
408                         .underlay.network.PolicyProfile.class, new org.opendaylight.yang.gen.v1.urn.opendaylight
409                         .netvirt.policy.rev170207.underlay.networks.underlay.network
410                         .PolicyProfileKey(policyClassifier));
411     }
412
413     public List<BigInteger> getUnderlayNetworkDpns(String underlayNetwork) {
414         return getDpnsFromDpnToInterfaces(getUnderlayNetworkDpnToInterfaces(underlayNetwork));
415     }
416
417     public List<BigInteger> getUnderlayNetworkRemoteDpns(String underlayNetwork) {
418         return getRemoteDpnsFromDpnToInterfaces(getUnderlayNetworkDpnToInterfaces(underlayNetwork));
419     }
420
421
422     public Optional<Integer> getLogicalTunnelLportTag(BigInteger srcDpId, BigInteger dstDpId) {
423         Optional<String> logicalTunnelNameOpt = getLogicalTunnelName(srcDpId, dstDpId);
424         if (!logicalTunnelNameOpt.isPresent()) {
425             LOG.debug("Failed to get logical tunnel for source DPN {} dst DPN {}", srcDpId, dstDpId);
426             return Optional.absent();
427         }
428
429         String logicalTunnelName = logicalTunnelNameOpt.get();
430         InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(logicalTunnelName);
431         if (interfaceInfo == null) {
432             LOG.debug("Failed to get interface info for logical tunnel {}", logicalTunnelName);
433             return Optional.absent();
434         }
435
436         return Optional.of(interfaceInfo.getInterfaceTag());
437     }
438
439     public Optional<String> getLogicalTunnelName(BigInteger srcDpId, BigInteger dstDpId) {
440         Future<RpcResult<GetTunnelInterfaceNameOutput>> tunnelInterfaceOutput = itmRpcService
441                 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
442                         .setDestinationDpid(dstDpId).setTunnelType(TunnelTypeLogicalGroup.class).build());
443         try {
444             if (tunnelInterfaceOutput.get().isSuccessful()) {
445                 return Optional.of(tunnelInterfaceOutput.get().getResult().getInterfaceName());
446             }
447         } catch (InterruptedException | ExecutionException e) {
448             LOG.error("Error in RPC call getTunnelInterfaceName {} for source DPN {} dst DPN {}", srcDpId, dstDpId);
449         }
450
451         return Optional.absent();
452     }
453 }