Fixes Bug 6469
[netvirt.git] / vpnservice / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / utils / AclServiceUtils.java
1 /*
2  * Copyright (c) 2016 Red Hat, Inc. 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.aclservice.utils;
10
11 import com.google.common.base.Optional;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
24 import org.opendaylight.genius.mdsalutil.MDSALUtil;
25 import org.opendaylight.genius.mdsalutil.MatchFieldType;
26 import org.opendaylight.genius.mdsalutil.MatchInfo;
27 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
28 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
29 import org.opendaylight.genius.mdsalutil.NwConstants;
30 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
31 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
32 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
33 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AccessLists;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
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.inet.types.rev130715.IpAddress;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
72 import org.opendaylight.yangtools.yang.binding.DataObject;
73 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
74 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
75 import org.opendaylight.yangtools.yang.common.RpcResult;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
78
79 @SuppressWarnings("deprecation")
80 public final class AclServiceUtils {
81
82     private static final Logger LOG = LoggerFactory.getLogger(AclServiceUtils.class);
83
84     private AclServiceUtils() { }
85
86     /**
87      * Retrieves the Interface from the datastore.
88      * @param broker the data broker
89      * @param interfaceName the interface name
90      * @return the interface.
91      */
92     public static Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
93         .Interface> getInterface(DataBroker broker, String interfaceName) {
94         return read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
95     }
96
97     /**
98      * Builds the interface identifier.
99      * @param interfaceName the interface name.
100      * @return the interface identifier.
101      */
102     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
103         .interfaces.Interface> getInterfaceIdentifier(String interfaceName) {
104         return InstanceIdentifier.builder(Interfaces.class)
105                 .child(
106                     org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
107                     .Interface.class, new InterfaceKey(interfaceName)).build();
108     }
109
110     /**
111      * Retrieves the object from the datastore.
112      * @param broker the data broker.
113      * @param datastoreType the data store type.
114      * @param path the wild card path.
115      * @return the required object.
116      */
117     public static <T extends DataObject> Optional<T> read(
118             DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
119
120         Optional<T> result = Optional.absent();
121         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
122         try {
123             result = tx.read(datastoreType, path).checkedGet();
124         } catch (ReadFailedException e) {
125             LOG.warn("Failed to read InstanceIdentifier {} from {}", path, datastoreType, e);
126         } finally {
127             tx.close();
128         }
129         return result;
130     }
131
132     /**
133      * Retrieves the acl matching the key from the data store.
134      *
135      * @param broker the data broker
136      * @param aclKey the acl key
137      * @return the acl
138      */
139     public static Acl getAcl(DataBroker broker, String aclKey) {
140         Optional<Acl> optAcl = read(broker,
141             LogicalDatastoreType.CONFIGURATION, getAclInstanceIdentifier(aclKey));
142         if (optAcl.isPresent()) {
143             return optAcl.get();
144         }
145         return null;
146     }
147
148     /** Creates the Acl instance identifier.
149      *
150      * @param aclKey the acl key
151      * @return the instance identifier
152      */
153     public static InstanceIdentifier<Acl> getAclInstanceIdentifier(String aclKey) {
154         return InstanceIdentifier
155                 .builder(AccessLists.class)
156                 .child(Acl.class,
157                         new AclKey(aclKey,Ipv4Acl.class))
158                 .build();
159     }
160
161     /**
162      * Get the data path number for the interface.
163      * @param interfaceManagerRpcService interfaceManagerRpcService instance.
164      * @param ifName the interface name.
165      * @return the dpn.
166      */
167     public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
168         BigInteger nodeId = BigInteger.ZERO;
169         try {
170             GetDpidFromInterfaceInput dpIdInput =
171                     new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
172             Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput =
173                     interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
174             RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
175             if (dpIdResult.isSuccessful()) {
176                 nodeId = dpIdResult.getResult().getDpid();
177             } else {
178                 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
179             }
180         } catch (NullPointerException | InterruptedException | ExecutionException e) {
181             LOG.error("Exception when getting dpn for interface {}", ifName,  e);
182         }
183         return nodeId;
184     }
185
186     /**
187      * Retrieves the interface state.
188      * @param dataBroker the data broker.
189      * @param interfaceName the interface name.
190      * @return the interface state.
191      */
192     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
193         .Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
194         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
195             .interfaces.state.Interface> ifStateId = buildStateInterfaceId(interfaceName);
196         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
197             .interfaces.state.Interface> ifStateOptional = MDSALUtil.read(LogicalDatastoreType
198                 .OPERATIONAL, ifStateId, dataBroker);
199         if (!ifStateOptional.isPresent()) {
200             return null;
201         }
202
203         return ifStateOptional.get();
204     }
205
206     /**
207      * Build the interface state.
208      * @param interfaceName the interface name.
209      * @return the interface state.
210      */
211     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
212         .interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
213         InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
214             .interfaces.state.Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
215             .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
216             .state.Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
217             .rev140508.interfaces.state.InterfaceKey(interfaceName));
218         return idBuilder.build();
219     }
220
221     /**
222      * Checks whether port security is enabled for the port.
223      * @param port the port.
224      * @return the port security is enabled/not.
225      */
226     public static boolean isPortSecurityEnabled(AclInterface port) {
227         return port.isPortSecurityEnabled();
228     }
229
230     /**
231      * Checks whether port security is enabled for the port.
232      * @param port the port.
233      * @return the list of security groups.
234      */
235     public static List<Uuid> getInterfaceAcls(Interface port) {
236         if (port == null) {
237             LOG.error("Port is Null");
238             return null;
239         }
240         InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
241         if (aclInPort == null) {
242             LOG.error("getSecurityGroupInPortList: no security group associated}",
243                 port.getName());
244             return null;
245         }
246         return aclInPort.getSecurityGroups();
247     }
248
249     /**
250      * Retrieves the security rule attribute augmentation from the access list.
251      * @param ace the access list entry
252      * @return the security rule attributes
253      */
254     public static SecurityRuleAttr  getAccesssListAttributes(Ace ace) {
255         if (ace == null) {
256             LOG.error("Ace is Null");
257             return null;
258         }
259         SecurityRuleAttr aceAttributes = ace.getAugmentation(SecurityRuleAttr.class);
260         if (aceAttributes == null) {
261             LOG.error("Ace is null");
262             return null;
263         }
264         return aceAttributes;
265     }
266
267     /**
268      * Returns the DHCP match.
269      *
270      * @param srcPort the source port.
271      * @param dstPort the destination port.
272      * @param lportTag the lport tag
273      * @return list of matches.
274      */
275     public static List<MatchInfoBase> buildDhcpMatches(int srcPort, int dstPort, int lportTag) {
276         List<MatchInfoBase> matches = new ArrayList<>(6);
277         matches.add(new MatchInfo(MatchFieldType.eth_type,
278                 new long[] { NwConstants.ETHTYPE_IPV4 }));
279         matches.add(new MatchInfo(MatchFieldType.ip_proto,
280                 new long[] { IPProtocols.UDP.intValue() }));
281         matches.add(new MatchInfo(MatchFieldType.udp_dst,
282                 new long[] { dstPort }));
283         matches.add(new MatchInfo(MatchFieldType.udp_src,
284                 new long[] { srcPort}));
285         matches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
286         return matches;
287     }
288
289     /**
290      * Builds the service id.
291      *
292      * @param interfaceName the interface name
293      * @param serviceIndex the service index
294      * @param serviceMode the service mode
295      * @return the instance identifier
296      */
297     public static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName, short serviceIndex,
298             Class<? extends ServiceModeBase> serviceMode) {
299         return InstanceIdentifier.builder(ServiceBindings.class)
300                 .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
301                 .child(BoundServices.class, new BoundServicesKey(serviceIndex)).build();
302     }
303
304     /**
305      * Gets the bound services.
306      *
307      * @param serviceName the service name
308      * @param servicePriority the service priority
309      * @param flowPriority the flow priority
310      * @param cookie the cookie
311      * @param instructions the instructions
312      * @return the bound services
313      */
314     public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
315             BigInteger cookie, List<Instruction> instructions) {
316         StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority)
317                 .setInstruction(instructions);
318         return new BoundServicesBuilder().setKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
319                 .setServicePriority(servicePriority).setServiceType(ServiceTypeFlowBased.class)
320                 .addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
321     }
322
323     public static List<Uuid> getUpdatedAclList(List<Uuid> updatedAclList, List<Uuid> currentAclList) {
324         if (updatedAclList == null) {
325             return null;
326         }
327         List<Uuid> newAclList = new ArrayList<>(updatedAclList);
328         if (currentAclList == null) {
329             return newAclList;
330         }
331         List<Uuid> origAclList = new ArrayList<>(currentAclList);
332         for (Iterator<Uuid> iterator = newAclList.iterator(); iterator.hasNext();) {
333             Uuid updatedAclUuid = iterator.next();
334             for (Uuid currentAclUuid :origAclList) {
335                 if (updatedAclUuid.getValue().equals(currentAclUuid.getValue())) {
336                     iterator.remove();
337                 }
338             }
339         }
340         return newAclList;
341     }
342
343     public static List<AllowedAddressPairs> getUpdatedAllowedAddressPairs(
344             List<AllowedAddressPairs> updatedAllowedAddressPairs,
345             List<AllowedAddressPairs> currentAllowedAddressPairs) {
346         if (updatedAllowedAddressPairs == null) {
347             return null;
348         }
349         List<AllowedAddressPairs> newAllowedAddressPairs = new ArrayList<>(updatedAllowedAddressPairs);
350         if (currentAllowedAddressPairs == null) {
351             return newAllowedAddressPairs;
352         }
353         List<AllowedAddressPairs> origAllowedAddressPairs = new ArrayList<>(currentAllowedAddressPairs);
354         for (Iterator<AllowedAddressPairs> iterator = newAllowedAddressPairs.iterator(); iterator.hasNext();) {
355             AllowedAddressPairs updatedAllowedAddressPair = iterator.next();
356             for (AllowedAddressPairs currentAllowedAddressPair : origAllowedAddressPairs) {
357                 if (updatedAllowedAddressPair.getKey().equals(currentAllowedAddressPair.getKey())) {
358                     iterator.remove();
359                     break;
360                 }
361             }
362         }
363         return newAllowedAddressPairs;
364     }
365
366     public static List<AllowedAddressPairs> getPortAllowedAddresses(Interface port) {
367         if (port == null) {
368             LOG.error("Port is Null");
369             return null;
370         }
371         InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
372         if (aclInPort == null) {
373             LOG.error("getSecurityGroupInPortList: no security group associated to Interface port: {}", port.getName());
374             return null;
375         }
376         return aclInPort.getAllowedAddressPairs();
377     }
378
379     public static BigInteger getDpIdFromIterfaceState(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
380             .interfaces.rev140508.interfaces.state.Interface interfaceState) {
381         BigInteger dpId = null;
382         List<String> ofportIds = interfaceState.getLowerLayerIf();
383         if (ofportIds != null && !ofportIds.isEmpty()) {
384             NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
385             dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
386         }
387         return dpId;
388     }
389
390     /**
391      * Builds the ip matches.
392      *
393      * @param ipPrefixOrAddress the ip prefix or address
394      * @param ipv4MatchType the ipv4 match type
395      * @return the list
396      */
397     public static List<MatchInfoBase> buildIpMatches(IpPrefixOrAddress ipPrefixOrAddress,
398             MatchFieldType ipv4MatchType) {
399         List<MatchInfoBase> flowMatches = new ArrayList<>();
400         flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4}));
401         IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
402         if (ipPrefix != null) {
403             if (ipPrefix.getIpv4Prefix().getValue() != null) {
404                 String[] ipaddressValues = ipPrefix.getIpv4Prefix().getValue().split("/");
405                 flowMatches.add(new MatchInfo(ipv4MatchType, new String[] {ipaddressValues[0], ipaddressValues[1]}));
406             } else {
407                 // Handle IPv6
408             }
409         } else {
410             IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
411             if (ipAddress.getIpv4Address() != null) {
412                 flowMatches
413                         .add(new MatchInfo(ipv4MatchType, new String[] {ipAddress.getIpv4Address().getValue(), "32"}));
414             } else {
415                 // Handle IPv6
416             }
417         }
418         return flowMatches;
419     }
420
421     /**
422      * Gets the lport tag match.
423      *
424      * @param lportTag the lport tag
425      * @return the lport tag match
426      */
427     public static MatchInfo buildLPortTagMatch(int lportTag) {
428         return new MatchInfo(MatchFieldType.metadata,
429                 new BigInteger[] {MetaDataUtil.getLportTagMetaData(lportTag), MetaDataUtil.METADATA_MASK_LPORT_TAG});
430     }
431
432     public static List<Ace> getAceWithRemoteAclId(DataBroker dataBroker, AclInterface port, Uuid remoteAcl) {
433         List<Ace> remoteAclRuleList = new ArrayList<>();
434         List<Uuid> aclList = port.getSecurityGroups();
435         for (Uuid aclId : aclList) {
436             Acl acl = getAcl(dataBroker, aclId.getValue());
437             List<Ace> aceList = acl.getAccessListEntries().getAce();
438             for (Ace ace : aceList) {
439                 Uuid tempRemoteAcl = getAccesssListAttributes(ace).getRemoteGroupId();
440                 if (tempRemoteAcl != null && tempRemoteAcl.equals(remoteAcl)) {
441                     remoteAclRuleList.add(ace);
442                 }
443             }
444         }
445         return remoteAclRuleList;
446     }
447
448     public static Map<String, List<MatchInfoBase>> getFlowForRemoteAcl(Uuid remoteAclId, String ignoreInterfaceId,
449                                                                        Map<String, List<MatchInfoBase>>
450                                                                                flowMatchesMap, boolean
451                                                                                isSourceIpMacMatch) {
452         List<AclInterface> interfaceList = AclDataUtil.getInterfaceList(remoteAclId);
453         if (flowMatchesMap == null || interfaceList == null || interfaceList.isEmpty()) {
454             return null;
455         }
456         Map<String, List<MatchInfoBase>> updatedFlowMatchesMap = new HashMap<>();
457         MatchInfoBase ipv4Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4});
458         for (String flowName : flowMatchesMap.keySet()) {
459             List<MatchInfoBase> flows = flowMatchesMap.get(flowName);
460             for (AclInterface port : interfaceList) {
461                 if (port.getInterfaceId().equals(ignoreInterfaceId)) {
462                     continue;
463                 }
464                 //get allow address pair
465                 List<AllowedAddressPairs> allowedAddressPair = port.getAllowedAddressPairs();
466                 // iterate over allow address pair and update match type
467                 for (AllowedAddressPairs aap : allowedAddressPair) {
468                     List<MatchInfoBase> matchInfoBaseList;
469                     String flowId;
470                     if (flows.contains(ipv4Match)) {
471                         matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
472                         flowId = flowName + "_ipv4_remoteACL_interface_aap_" + aap.getKey();
473                     } else {
474                         // TODO: handle AAP matches for ipv6
475                         matchInfoBaseList = flows;
476                         flowId = flowName + "_ipv6_remoteACL_interface_aap_" +  aap.getKey();
477                     }
478                     updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
479                 }
480
481             }
482
483         }
484         return updatedFlowMatchesMap;
485     }
486
487     public static Map<String, List<MatchInfoBase>> getFlowForAllowedAddresses(List<AllowedAddressPairs>
488                                                                                       syncAllowedAddresses,
489                                                                               Map<String, List<MatchInfoBase>>
490                                                                                       flowMatchesMap, boolean
491                                                                                       isSourceIpMacMatch) {
492         if (flowMatchesMap == null) {
493             return null;
494         }
495         Map<String, List<MatchInfoBase>> updatedFlowMatchesMap = new HashMap<>();
496         MatchInfoBase ipv4Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4});
497         for (String flowName : flowMatchesMap.keySet()) {
498             List<MatchInfoBase> flows = flowMatchesMap.get(flowName);
499             // iterate over allow address pair and update match type
500             for (AllowedAddressPairs aap : syncAllowedAddresses) {
501                 List<MatchInfoBase> matchInfoBaseList;
502                 String flowId;
503                 if (flows.contains(ipv4Match)) {
504                     matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
505                     flowId = flowName + "_ipv4_remoteACL_interface_aap_" + aap.getKey();
506                 } else {
507                     // TODO: handle AAP matches for ipv6
508                     matchInfoBaseList = flows;
509                     flowId = flowName + "_ipv6_remoteACL_interface_aap_" + aap.getKey();
510                 }
511                 updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
512             }
513
514         }
515         return updatedFlowMatchesMap;
516     }
517
518     public static Long getElanIdFromInterface(String elanInterfaceName,DataBroker broker) {
519         ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(elanInterfaceName, broker);
520         if (null != elanInterface) {
521             ElanInstance elanInfo = getElanInstanceByName(elanInterface.getElanInstanceName(), broker);
522             return elanInfo.getElanTag();
523         }
524         return null;
525     }
526
527     public static ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName,DataBroker broker) {
528         InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
529         Optional<ElanInterface> existingElanInterface = read(broker,
530                 LogicalDatastoreType.CONFIGURATION, elanInterfaceId);
531         if (existingElanInterface.isPresent()) {
532             return existingElanInterface.get();
533         }
534         return null;
535     }
536
537     public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
538         return InstanceIdentifier.builder(ElanInterfaces.class)
539                 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
540     }
541
542     // elan-instances config container
543     public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
544         InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
545         Optional<ElanInstance> elanInstance = read(broker, LogicalDatastoreType.CONFIGURATION,
546                 elanIdentifierId);
547         if (elanInstance.isPresent()) {
548             return elanInstance.get();
549         }
550         return null;
551     }
552
553     public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
554         return InstanceIdentifier.builder(ElanInstances.class)
555                 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
556     }
557
558     private static List<MatchInfoBase> updateAAPMatches(boolean isSourceIpMacMatch, List<MatchInfoBase> flows,
559                                                         AllowedAddressPairs aap) {
560         List<MatchInfoBase> matchInfoBaseList;
561         if (isSourceIpMacMatch) {
562             matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchFieldType.ipv4_source);
563         } else {
564             matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchFieldType.ipv4_destination);
565         }
566         matchInfoBaseList.addAll(flows);
567         return matchInfoBaseList;
568     }
569
570     public static MatchInfoBase popMatchInfoByType(List<MatchInfoBase> flows, MatchFieldType type) {
571         MatchInfoBase mib = getMatchInfoByType(flows, type);
572         if (mib != null) {
573             flows.remove(mib);
574         }
575         return mib;
576     }
577
578     public static MatchInfoBase getMatchInfoByType(List<MatchInfoBase> flows, MatchFieldType type) {
579         for (MatchInfoBase mib : flows) {
580             if (mib instanceof MatchInfo) {
581                 if (((MatchInfo)mib).getMatchField() == type) {
582                     return mib;
583                 }
584             }
585         }
586         return null;
587     }
588
589     public static MatchInfoBase getMatchInfoByType(List<MatchInfoBase> flows, NxMatchFieldType type) {
590         for (MatchInfoBase mib : flows) {
591             if (mib instanceof NxMatchInfo) {
592                 if (((NxMatchInfo)mib).getMatchField() == type) {
593                     return mib;
594                 }
595             }
596         }
597         return null;
598     }
599
600     public static boolean containsMatchFieldType(List<MatchInfoBase> flows, MatchFieldType type) {
601         MatchInfoBase mib = getMatchInfoByType(flows, type);
602         if (mib != null) {
603             return true;
604         }
605         return false;
606     }
607
608     public static boolean containsMatchFieldType(List<MatchInfoBase> flows, NxMatchFieldType type) {
609         MatchInfoBase mib = getMatchInfoByType(flows, type);
610         if (mib != null) {
611             return true;
612         }
613         return false;
614     }
615 }