cdd617333806836c277c6295d7444e537309d695
[netvirt.git] / vpnservice / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / utils / AclServiceUtils.java
1 /*
2  * Copyright © 2016, 2017 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 javax.inject.Inject;
21 import javax.inject.Singleton;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
26 import org.opendaylight.genius.interfacemanager.globals.InterfaceServiceUtil;
27 import org.opendaylight.genius.mdsalutil.MDSALUtil;
28 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
29 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
30 import org.opendaylight.genius.mdsalutil.NwConstants;
31 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
32 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
33 import org.opendaylight.genius.mdsalutil.matches.MatchIcmpv6;
34 import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol;
35 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
36 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Source;
37 import org.opendaylight.genius.mdsalutil.matches.MatchIpv6Destination;
38 import org.opendaylight.genius.mdsalutil.matches.MatchIpv6Source;
39 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
40 import org.opendaylight.genius.mdsalutil.matches.MatchUdpDestinationPort;
41 import org.opendaylight.genius.mdsalutil.matches.MatchUdpSourcePort;
42 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister;
43 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.MatchCriteria;
44 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AccessLists;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
50 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.PacketHandling;
51 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.packet.handling.Permit;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolInputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
100 import org.opendaylight.yangtools.yang.binding.DataObject;
101 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
102 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
103 import org.opendaylight.yangtools.yang.common.RpcResult;
104 import org.slf4j.Logger;
105 import org.slf4j.LoggerFactory;
106
107 @Singleton
108 @SuppressWarnings("deprecation")
109 public final class AclServiceUtils {
110
111     private static final Logger LOG = LoggerFactory.getLogger(AclServiceUtils.class);
112     public static final AclserviceConfig.DefaultBehavior DEFAULT_DENY = AclserviceConfig.DefaultBehavior.Deny;
113     public static final AclserviceConfig.DefaultBehavior DEFAULT_ALLOW = AclserviceConfig.DefaultBehavior.Allow;
114
115     private final AclDataUtil aclDataUtil;
116     private final AclserviceConfig config;
117     private final IdManagerService idManager;
118
119     @Inject
120     public AclServiceUtils(AclDataUtil aclDataUtil, AclserviceConfig config, IdManagerService idManager) {
121         super();
122         this.aclDataUtil = aclDataUtil;
123         this.config = config;
124         this.idManager = idManager;
125     }
126
127     /**
128      * Retrieves the Interface from the datastore.
129      * @param broker the data broker
130      * @param interfaceName the interface name
131      * @return the interface.
132      */
133     public static Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
134         .Interface> getInterface(DataBroker broker, String interfaceName) {
135         return read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
136     }
137
138     /**
139      * Builds the interface identifier.
140      * @param interfaceName the interface name.
141      * @return the interface identifier.
142      */
143     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
144         .interfaces.Interface> getInterfaceIdentifier(String interfaceName) {
145         return InstanceIdentifier.builder(Interfaces.class)
146                 .child(
147                     org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
148                     .Interface.class, new InterfaceKey(interfaceName)).build();
149     }
150
151     /**
152      * Retrieves the object from the datastore.
153      * @param broker the data broker.
154      * @param datastoreType the data store type.
155      * @param path the wild card path.
156      * @param <T> type of DataObject
157      * @return the required object.
158      */
159     public static <T extends DataObject> Optional<T> read(
160             DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
161         try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
162             return tx.read(datastoreType, path).checkedGet();
163         } catch (ReadFailedException e) {
164             LOG.warn("Failed to read InstanceIdentifier {} from {}", path, datastoreType, e);
165             return Optional.absent();
166         }
167     }
168
169     /**
170      * Retrieves the acl matching the key from the data store.
171      *
172      * @param broker the data broker
173      * @param aclKey the acl key
174      * @return the acl
175      */
176     public static Acl getAcl(DataBroker broker, String aclKey) {
177         return read(broker, LogicalDatastoreType.CONFIGURATION, getAclInstanceIdentifier(aclKey)).orNull();
178     }
179
180     /** Creates the Acl instance identifier.
181      *
182      * @param aclKey the acl key
183      * @return the instance identifier
184      */
185     public static InstanceIdentifier<Acl> getAclInstanceIdentifier(String aclKey) {
186         return InstanceIdentifier
187                 .builder(AccessLists.class)
188                 .child(Acl.class,
189                         new AclKey(aclKey,Ipv4Acl.class))
190                 .build();
191     }
192
193     /**
194      * Get the data path number for the interface.
195      * @param interfaceManagerRpcService interfaceManagerRpcService instance.
196      * @param ifName the interface name.
197      * @return the dpn.
198      */
199     public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
200         BigInteger nodeId = BigInteger.ZERO;
201         try {
202             GetDpidFromInterfaceInput dpIdInput =
203                     new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
204             Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput =
205                     interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
206             RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
207             if (dpIdResult.isSuccessful()) {
208                 nodeId = dpIdResult.getResult().getDpid();
209             } else {
210                 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
211             }
212         } catch (NullPointerException | InterruptedException | ExecutionException e) {
213             LOG.error("Exception when getting dpn for interface {}", ifName,  e);
214         }
215         return nodeId;
216     }
217
218     /**
219      * Retrieves the interface state.
220      * @param dataBroker the data broker.
221      * @param interfaceName the interface name.
222      * @return the interface state.
223      */
224     public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
225         .Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
226         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
227             .interfaces.state.Interface> ifStateId = buildStateInterfaceId(interfaceName);
228         return MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker).orNull();
229     }
230
231     /**
232      * Build the interface state.
233      * @param interfaceName the interface name.
234      * @return the interface state.
235      */
236     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
237         .interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
238         InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
239             .interfaces.state.Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
240             .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
241             .state.Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
242             .rev140508.interfaces.state.InterfaceKey(interfaceName));
243         return idBuilder.build();
244     }
245
246     /**
247      * Checks whether port security is enabled for the port.
248      * @param port the port.
249      * @return the port security is enabled/not.
250      */
251     public static boolean isPortSecurityEnabled(AclInterface port) {
252         return port.isPortSecurityEnabled();
253     }
254
255     /**
256      * Checks whether port security is enabled for the port.
257      * @param port the port.
258      * @return the list of security groups.
259      */
260     public static List<Uuid> getInterfaceAcls(Interface port) {
261         if (port == null) {
262             LOG.error("Port is Null");
263             return null;
264         }
265         InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
266         if (aclInPort == null) {
267             LOG.error("getSecurityGroupInPortList: no security group associated}",
268                 port.getName());
269             return null;
270         }
271         return aclInPort.getSecurityGroups();
272     }
273
274     /**
275      * Retrieves the security rule attribute augmentation from the access list.
276      * @param ace the access list entry
277      * @return the security rule attributes
278      */
279     public static SecurityRuleAttr  getAccesssListAttributes(Ace ace) {
280         if (ace == null) {
281             LOG.error("Ace is Null");
282             return null;
283         }
284         SecurityRuleAttr aceAttributes = ace.getAugmentation(SecurityRuleAttr.class);
285         if (aceAttributes == null) {
286             LOG.error("Ace is null");
287             return null;
288         }
289         return aceAttributes;
290     }
291
292     /**
293      * Returns the DHCP match.
294      *
295      * @param srcPort the source port.
296      * @param dstPort the destination port.
297      * @param lportTag the lport tag
298      * @param serviceMode ingress or egress service
299      * @return list of matches.
300      */
301     public static List<MatchInfoBase> buildDhcpMatches(int srcPort, int dstPort, int lportTag,
302             Class<? extends ServiceModeBase> serviceMode) {
303         List<MatchInfoBase> matches = new ArrayList<>(6);
304         matches.add(MatchEthernetType.IPV4);
305         matches.add(MatchIpProtocol.UDP);
306         matches.add(new MatchUdpDestinationPort(dstPort));
307         matches.add(new MatchUdpSourcePort(srcPort));
308         matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
309         return matches;
310     }
311
312     /**
313      * Returns the DHCPv6 match.
314      *
315      * @param srcPort the source port.
316      * @param dstPort the destination port.
317      * @param lportTag the lport tag
318      * @param serviceMode ingress or egress
319      * @return list of matches.
320      */
321     public static List<MatchInfoBase> buildDhcpV6Matches(int srcPort, int dstPort, int lportTag,
322             Class<? extends ServiceModeBase> serviceMode) {
323         List<MatchInfoBase> matches = new ArrayList<>(6);
324         matches.add(MatchEthernetType.IPV6);
325         matches.add(MatchIpProtocol.UDP);
326         matches.add(new MatchUdpDestinationPort(dstPort));
327         matches.add(new MatchUdpSourcePort(srcPort));
328         matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
329         return matches;
330     }
331
332     /**
333      * Returns the ICMPv6 match.
334      *
335      * @param icmpType the icmpv6-type.
336      * @param icmpCode the icmpv6-code.
337      * @param lportTag the lport tag
338      * @param serviceMode ingress or egress
339      * @return list of matches.
340      */
341     public static List<MatchInfoBase> buildIcmpV6Matches(int icmpType, int icmpCode, int lportTag,
342             Class<? extends ServiceModeBase> serviceMode) {
343         List<MatchInfoBase> matches = new ArrayList<>(6);
344         matches.add(MatchEthernetType.IPV6);
345         matches.add(MatchIpProtocol.ICMPV6);
346         if (icmpType != 0) {
347             matches.add(new MatchIcmpv6((short) icmpType, (short) icmpCode));
348         }
349         matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
350         return matches;
351     }
352
353     /**
354      * Builds the service id.
355      *
356      * @param interfaceName the interface name
357      * @param serviceIndex the service index
358      * @param serviceMode the service mode
359      * @return the instance identifier
360      */
361     public static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName, short serviceIndex,
362             Class<? extends ServiceModeBase> serviceMode) {
363         return InstanceIdentifier.builder(ServiceBindings.class)
364                 .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
365                 .child(BoundServices.class, new BoundServicesKey(serviceIndex)).build();
366     }
367
368     /**
369      * Gets the bound services.
370      *
371      * @param serviceName the service name
372      * @param servicePriority the service priority
373      * @param flowPriority the flow priority
374      * @param cookie the cookie
375      * @param instructions the instructions
376      * @return the bound services
377      */
378     public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
379             BigInteger cookie, List<Instruction> instructions) {
380         StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority)
381                 .setInstruction(instructions);
382         return new BoundServicesBuilder().setKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
383                 .setServicePriority(servicePriority).setServiceType(ServiceTypeFlowBased.class)
384                 .addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
385     }
386
387     public static List<Uuid> getUpdatedAclList(List<Uuid> updatedAclList, List<Uuid> currentAclList) {
388         if (updatedAclList == null) {
389             return null;
390         }
391         List<Uuid> newAclList = new ArrayList<>(updatedAclList);
392         if (currentAclList == null) {
393             return newAclList;
394         }
395         List<Uuid> origAclList = new ArrayList<>(currentAclList);
396         for (Iterator<Uuid> iterator = newAclList.iterator(); iterator.hasNext();) {
397             Uuid updatedAclUuid = iterator.next();
398             for (Uuid currentAclUuid :origAclList) {
399                 if (updatedAclUuid.getValue().equals(currentAclUuid.getValue())) {
400                     iterator.remove();
401                 }
402             }
403         }
404         return newAclList;
405     }
406
407     public static List<AllowedAddressPairs> getUpdatedAllowedAddressPairs(
408             List<AllowedAddressPairs> updatedAllowedAddressPairs,
409             List<AllowedAddressPairs> currentAllowedAddressPairs) {
410         if (updatedAllowedAddressPairs == null) {
411             return null;
412         }
413         List<AllowedAddressPairs> newAllowedAddressPairs = new ArrayList<>(updatedAllowedAddressPairs);
414         if (currentAllowedAddressPairs == null) {
415             return newAllowedAddressPairs;
416         }
417         List<AllowedAddressPairs> origAllowedAddressPairs = new ArrayList<>(currentAllowedAddressPairs);
418         for (Iterator<AllowedAddressPairs> iterator = newAllowedAddressPairs.iterator(); iterator.hasNext();) {
419             AllowedAddressPairs updatedAllowedAddressPair = iterator.next();
420             for (AllowedAddressPairs currentAllowedAddressPair : origAllowedAddressPairs) {
421                 if (updatedAllowedAddressPair.getKey().equals(currentAllowedAddressPair.getKey())) {
422                     iterator.remove();
423                     break;
424                 }
425             }
426         }
427         return newAllowedAddressPairs;
428     }
429
430     public static List<AllowedAddressPairs> getPortAllowedAddresses(Interface port) {
431         if (port == null) {
432             LOG.error("Port is Null");
433             return null;
434         }
435         InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
436         if (aclInPort == null) {
437             LOG.error("getSecurityGroupInPortList: no security group associated to Interface port: {}", port.getName());
438             return null;
439         }
440         return aclInPort.getAllowedAddressPairs();
441     }
442
443     public static BigInteger getDpIdFromIterfaceState(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
444             .interfaces.rev140508.interfaces.state.Interface interfaceState) {
445         BigInteger dpId = null;
446         List<String> ofportIds = interfaceState.getLowerLayerIf();
447         if (ofportIds != null && !ofportIds.isEmpty()) {
448             NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
449             dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
450         }
451         return dpId;
452     }
453
454     /**
455      * Builds the ip matches.
456      *
457      * @param ipPrefixOrAddress the ip prefix or address
458      * @param matchCriteria the source_ip or destination_ip used for the match
459      * @return the list
460      */
461     public static List<MatchInfoBase> buildIpMatches(IpPrefixOrAddress ipPrefixOrAddress,
462                                                      MatchCriteria matchCriteria) {
463         List<MatchInfoBase> flowMatches = new ArrayList<>();
464         IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
465         if (ipPrefix != null) {
466             Ipv4Prefix ipv4Prefix = ipPrefix.getIpv4Prefix();
467             if (ipv4Prefix != null) {
468                 flowMatches.add(MatchEthernetType.IPV4);
469                 if (!ipv4Prefix.getValue().equals(AclConstants.IPV4_ALL_NETWORK)) {
470                     flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv4Source(ipv4Prefix)
471                             : new MatchIpv4Destination(ipv4Prefix));
472                 }
473             } else {
474                 flowMatches.add(MatchEthernetType.IPV6);
475                 flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv6Source(
476                         ipPrefix.getIpv6Prefix()) : new MatchIpv6Destination(ipPrefix.getIpv6Prefix()));
477             }
478         } else {
479             IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
480             if (ipAddress.getIpv4Address() != null) {
481                 flowMatches.add(MatchEthernetType.IPV4);
482                 flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv4Source(
483                         ipAddress.getIpv4Address().getValue(), "32") : new MatchIpv4Destination(
484                         ipAddress.getIpv4Address().getValue(), "32"));
485             } else {
486                 flowMatches.add(MatchEthernetType.IPV6);
487                 flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv6Source(
488                         ipAddress.getIpv6Address().getValue() + "/128") : new MatchIpv6Destination(
489                         ipAddress.getIpv6Address().getValue() + "/128"));
490             }
491         }
492         return flowMatches;
493     }
494
495     private List<MatchInfoBase> buildAclIdMetadataMatch(Uuid remoteAclId) {
496         List<MatchInfoBase> flowMatches = new ArrayList<>();
497         BigInteger aclId = buildAclId(remoteAclId);
498         if (aclId.intValue() != AclConstants.INVALID_ACL_ID) {
499             MatchMetadata metadataMatch = new MatchMetadata(getAclIdMetadata(aclId),
500                     MetaDataUtil.METADATA_MASK_REMOTE_ACL_ID);
501             flowMatches.add(metadataMatch);
502         } else {
503             LOG.warn("Failed building metadata match for Acl id match. Failed to allocate id");
504         }
505         return flowMatches;
506     }
507
508     public BigInteger buildAclId(Uuid remoteAclId) {
509         Integer aclId = allocateAclId(remoteAclId.getValue());
510         return BigInteger.valueOf(aclId);
511     }
512
513     public static BigInteger getAclIdMetadata(BigInteger aclId) {
514         return aclId.shiftLeft(1);
515     }
516
517     /**
518      * Gets the lport tag match.
519      * Ingress match is based on metadata and egress match is based on masked reg6
520      *
521      * @param lportTag the lport tag
522      * @param serviceMode ingress or egress service mode
523      * @return the lport tag match
524      */
525     public static MatchInfoBase buildLPortTagMatch(int lportTag, Class<? extends ServiceModeBase> serviceMode) {
526         if (serviceMode != null && serviceMode.isAssignableFrom(ServiceModeIngress.class)) {
527             return new NxMatchRegister(NxmNxReg6.class, MetaDataUtil.getLportTagForReg6(lportTag).longValue(),
528                     MetaDataUtil.getLportTagMaskForReg6());
529         } else {
530             return new MatchMetadata(MetaDataUtil.getLportTagMetaData(lportTag), MetaDataUtil.METADATA_MASK_LPORT_TAG);
531         }
532     }
533
534     public static List<Ace> getAceWithRemoteAclId(DataBroker dataBroker, AclInterface port, Uuid remoteAcl) {
535         List<Ace> remoteAclRuleList = new ArrayList<>();
536         List<Uuid> aclList = port.getSecurityGroups();
537         for (Uuid aclId : aclList) {
538             Acl acl = getAcl(dataBroker, aclId.getValue());
539             List<Ace> aceList = acl.getAccessListEntries().getAce();
540             for (Ace ace : aceList) {
541                 Uuid tempRemoteAcl = getAccesssListAttributes(ace).getRemoteGroupId();
542                 if (tempRemoteAcl != null && tempRemoteAcl.equals(remoteAcl)) {
543                     remoteAclRuleList.add(ace);
544                 }
545             }
546         }
547         return remoteAclRuleList;
548     }
549
550     public Map<String, List<MatchInfoBase>> getFlowForRemoteAcl(Uuid remoteAclId, String ignoreInterfaceId,
551             Map<String, List<MatchInfoBase>> flowMatchesMap, boolean isSourceIpMacMatch) {
552         List<AclInterface> interfaceList = aclDataUtil.getInterfaceList(remoteAclId);
553         if (flowMatchesMap == null || interfaceList == null || interfaceList.isEmpty()) {
554             return null;
555         }
556         Map<String, List<MatchInfoBase>> updatedFlowMatchesMap = new HashMap<>();
557         MatchInfoBase ipv4Match = MatchEthernetType.IPV4;
558         MatchInfoBase ipv6Match = MatchEthernetType.IPV6;
559         for (String flowName : flowMatchesMap.keySet()) {
560             List<MatchInfoBase> flows = flowMatchesMap.get(flowName);
561             for (AclInterface port : interfaceList) {
562                 if (port.getInterfaceId().equals(ignoreInterfaceId)) {
563                     continue;
564                 }
565
566                 if (port.getSecurityGroups() != null && port.getSecurityGroups().size() == 1) {
567                     LOG.debug(
568                             "port {} is in only one SG. "
569                                     + "Doesn't adding it's IPs {} to matches (handled in acl id match)",
570                             port.getLPortTag(), port.getAllowedAddressPairs());
571                     List<MatchInfoBase> matchInfoBaseList = addFlowMatchForAclId(remoteAclId, flows);
572                     String flowId = flowName + "_remoteACL_id_" + remoteAclId.getValue();
573                     updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
574                     continue;
575                 }
576                 // get allow address pair
577                 List<AllowedAddressPairs> allowedAddressPair = port.getAllowedAddressPairs();
578                 // iterate over allow address pair and update match type
579                 for (AllowedAddressPairs aap : allowedAddressPair) {
580                     List<MatchInfoBase> matchInfoBaseList;
581                     String flowId;
582                     if (flows.contains(ipv4Match) && isIPv4Address(aap) && isNotIpv4AllNetwork(aap)) {
583                         matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
584                         flowId = flowName + "_ipv4_remoteACL_interface_aap_" + getAapFlowId(aap);
585                         updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
586                     } else if (flows.contains(ipv6Match) && !isIPv4Address(aap) && isNotIpv6AllNetwork(aap)) {
587                         matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
588                         flowId = flowName + "_ipv6_remoteACL_interface_aap_" + getAapFlowId(aap);
589                         updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
590                     }
591                 }
592             }
593         }
594         return updatedFlowMatchesMap;
595     }
596
597     public AclserviceConfig getConfig() {
598         return config;
599     }
600
601     private static boolean isIPv4Address(AllowedAddressPairs aap) {
602         IpPrefixOrAddress ipPrefixOrAddress = aap.getIpAddress();
603         IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
604         if (ipPrefix != null) {
605             if (ipPrefix.getIpv4Prefix() != null) {
606                 return true;
607             }
608         } else {
609             IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
610             if (ipAddress.getIpv4Address() != null) {
611                 return true;
612             }
613         }
614         return false;
615     }
616
617     public static Map<String, List<MatchInfoBase>> getFlowForAllowedAddresses(
618             List<AllowedAddressPairs> syncAllowedAddresses, Map<String, List<MatchInfoBase>> flowMatchesMap,
619             boolean isSourceIpMacMatch) {
620         if (flowMatchesMap == null) {
621             return null;
622         }
623         Map<String, List<MatchInfoBase>> updatedFlowMatchesMap = new HashMap<>();
624         MatchInfoBase ipv4Match = MatchEthernetType.IPV4;
625         MatchInfoBase ipv6Match = MatchEthernetType.IPV6;
626         for (String flowName : flowMatchesMap.keySet()) {
627             List<MatchInfoBase> flows = flowMatchesMap.get(flowName);
628             // iterate over allow address pair and update match type
629             for (AllowedAddressPairs aap : syncAllowedAddresses) {
630                 List<MatchInfoBase> matchInfoBaseList;
631                 String flowId;
632                 if (flows.contains(ipv4Match) && isIPv4Address(aap) && isNotIpv4AllNetwork(aap)) {
633                     matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
634                     flowId = flowName + "_ipv4_remoteACL_interface_aap_" + getAapFlowId(aap);
635                     updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
636                 } else if (flows.contains(ipv6Match) && !isIPv4Address(aap) && isNotIpv6AllNetwork(aap)) {
637                     matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
638                     flowId = flowName + "_ipv6_remoteACL_interface_aap_" + getAapFlowId(aap);
639                     updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
640                 }
641             }
642         }
643         return updatedFlowMatchesMap;
644     }
645
646     public static boolean isNotIpv4AllNetwork(AllowedAddressPairs aap) {
647         IpPrefix ipPrefix = aap.getIpAddress().getIpPrefix();
648         if (ipPrefix != null && ipPrefix.getIpv4Prefix() != null
649                 && ipPrefix.getIpv4Prefix().getValue().equals(AclConstants.IPV4_ALL_NETWORK)) {
650             return false;
651         }
652         return true;
653     }
654
655     protected static boolean isNotIpv6AllNetwork(AllowedAddressPairs aap) {
656         IpPrefix ipPrefix = aap.getIpAddress().getIpPrefix();
657         if (ipPrefix != null && ipPrefix.getIpv6Prefix() != null
658                 && ipPrefix.getIpv6Prefix().getValue().equals(AclConstants.IPV6_ALL_NETWORK)) {
659             return false;
660         }
661         return true;
662     }
663
664     private static String getAapFlowId(AllowedAddressPairs aap) {
665         return aap.getMacAddress().getValue() + "_" + String.valueOf(aap.getIpAddress().getValue());
666     }
667
668     public static Long getElanIdFromInterface(String elanInterfaceName,DataBroker broker) {
669         ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(elanInterfaceName, broker);
670         if (null != elanInterface) {
671             ElanInstance elanInfo = getElanInstanceByName(elanInterface.getElanInstanceName(), broker);
672             return elanInfo.getElanTag();
673         }
674         return null;
675     }
676
677     public static ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName,DataBroker broker) {
678         InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
679         return read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull();
680     }
681
682     public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
683         return InstanceIdentifier.builder(ElanInterfaces.class)
684                 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
685     }
686
687     // elan-instances config container
688     public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
689         InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
690         return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
691     }
692
693     public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
694         return InstanceIdentifier.builder(ElanInstances.class)
695                 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
696     }
697
698     private static List<MatchInfoBase> updateAAPMatches(boolean isSourceIpMacMatch, List<MatchInfoBase> flows,
699                                                         AllowedAddressPairs aap) {
700         List<MatchInfoBase> matchInfoBaseList;
701         if (isSourceIpMacMatch) {
702             matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchCriteria.MATCH_SOURCE);
703         } else {
704             matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchCriteria.MATCH_DESTINATION);
705         }
706         matchInfoBaseList.addAll(flows);
707         return matchInfoBaseList;
708     }
709
710     private List<MatchInfoBase> addFlowMatchForAclId(Uuid remoteAclId, List<MatchInfoBase> flows) {
711         List<MatchInfoBase> matchInfoBaseList;
712         matchInfoBaseList = buildAclIdMetadataMatch(remoteAclId);
713         matchInfoBaseList.addAll(flows);
714         return matchInfoBaseList;
715     }
716
717     public static MatchInfoBase getMatchInfoByType(List<MatchInfoBase> flows, Class<? extends NxMatchInfo> type) {
718         for (MatchInfoBase mib : flows) {
719             if (type.isAssignableFrom(mib.getClass())) {
720                 return mib;
721             }
722         }
723         return null;
724     }
725
726     public static boolean containsMatchFieldType(List<MatchInfoBase> flows, Class<? extends NxMatchInfo> type) {
727         return getMatchInfoByType(flows, type) != null;
728     }
729
730     public static boolean containsTcpMatchField(List<MatchInfoBase> flows) {
731         return flows.contains(MatchIpProtocol.TCP);
732     }
733
734     public static boolean containsUdpMatchField(List<MatchInfoBase> flows) {
735         return flows.contains(MatchIpProtocol.UDP);
736     }
737
738     public static Integer allocateId(IdManagerService idManager, String poolName, String idKey, Integer defaultId) {
739         AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
740         try {
741             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
742             RpcResult<AllocateIdOutput> rpcResult = result.get();
743             if (rpcResult.isSuccessful()) {
744                 return rpcResult.getResult().getIdValue().intValue();
745             } else {
746                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
747             }
748         } catch (InterruptedException | ExecutionException e) {
749             LOG.warn("Exception when getting Unique Id", e);
750         }
751         return defaultId;
752     }
753
754     public static void releaseId(IdManagerService idManager, String poolName, String idKey) {
755         ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
756         try {
757             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
758             RpcResult<Void> rpcResult = result.get();
759             if (!rpcResult.isSuccessful()) {
760                 LOG.warn("RPC Call to release Id {} with Key {} returned with Errors {}", idKey, rpcResult.getErrors());
761             }
762         } catch (InterruptedException | ExecutionException e) {
763             LOG.warn("Exception when releasing Id for key {}", idKey, e);
764         }
765     }
766
767     /**
768      * Allocate and save flow priority in cache.
769      *
770      * @param key the key
771      * @return the integer
772      */
773     public Integer allocateAndSaveFlowPriorityInCache(BigInteger dpId, short tableId, String key,
774                                                       PacketHandling packetHandling) {
775         String poolName = getAclPoolName(dpId, tableId, packetHandling);
776         Integer flowPriority = AclServiceUtils.allocateId(this.idManager, poolName, key,
777                 AclConstants.PROTO_MATCH_PRIORITY);
778         this.aclDataUtil.addAclFlowPriority(key, flowPriority);
779         return flowPriority;
780     }
781
782     /**
783      * Allocate acl id.
784      *
785      * @param key the key
786      */
787     public Integer allocateAclId(String key) {
788         Integer aclId = AclServiceUtils.allocateId(this.idManager, AclConstants.ACL_ID_POOL_NAME, key,
789                 AclConstants.INVALID_ACL_ID);
790         return aclId;
791     }
792
793     /**
794     * Allocate and save flow priority in cache.
795     *
796     * @param key the key
797     */
798     public void releaseAclId(String key) {
799         AclServiceUtils.releaseId(idManager, AclConstants.ACL_ID_POOL_NAME, key);
800     }
801
802     /**
803      * Release and remove flow priority from cache.
804      *
805      * @param key the key
806      * @return the integer
807      */
808     public Integer releaseAndRemoveFlowPriorityFromCache(BigInteger dpId, short tableId, String key,
809                                                          PacketHandling packetHandling) {
810         String poolName = getAclPoolName(dpId, tableId, packetHandling);
811         AclServiceUtils.releaseId(this.idManager, poolName, key);
812         Integer flowPriority = this.aclDataUtil.removeAclFlowPriority(key);
813         if (flowPriority == null) {
814             flowPriority = AclConstants.PROTO_MATCH_PRIORITY;
815         }
816         return flowPriority;
817     }
818
819     /**
820      * Indicates whether the interface has port security enabled.
821      * @param aclInterface the interface.
822      * @return true if port is security enabled.
823      */
824     public static boolean isOfInterest(AclInterface aclInterface) {
825         return aclInterface != null && aclInterface.getPortSecurityEnabled() != null
826                 && aclInterface.isPortSecurityEnabled();
827     }
828
829     /**
830      * Creates the id pool.
831      *
832      * @param poolName the pool name
833      */
834     public void createIdPool(String poolName, AclConstants.PacketHandlingType packetHandlingType) {
835         CreateIdPoolInput createPool = null;
836
837         // If the default behavior is Deny, then ACLs with Allow packetHandling must have lower priority than
838         // ACLs with Deny packetHandling - otherwise the Deny ACLs are redundant, and vice versa
839         if ((config.getDefaultBehavior() == DEFAULT_DENY
840                 && packetHandlingType == AclConstants.PacketHandlingType.PERMIT)
841                 || (config.getDefaultBehavior() == DEFAULT_ALLOW
842                     && packetHandlingType == AclConstants.PacketHandlingType.DENY)) {
843             createPool = new CreateIdPoolInputBuilder()
844                     .setPoolName(poolName).setLow(AclConstants.ACL_FLOW_PRIORITY_LOW_POOL_START)
845                     .setHigh(AclConstants.ACL_FLOW_PRIORITY_LOW_POOL_END).build();
846         } else if ((config.getDefaultBehavior() == DEFAULT_DENY
847                 && packetHandlingType == AclConstants.PacketHandlingType.DENY)
848                 || (config.getDefaultBehavior() == DEFAULT_ALLOW
849                     && packetHandlingType == AclConstants.PacketHandlingType.PERMIT)) {
850             createPool = new CreateIdPoolInputBuilder()
851                     .setPoolName(poolName).setLow(AclConstants.ACL_FLOW_PRIORITY_HIGH_POOL_START)
852                     .setHigh(AclConstants.ACL_FLOW_PRIORITY_HIGH_POOL_END).build();
853         } else {
854             LOG.error("Got unexpected PacketHandling {} combined with default behavior {}, skipping creation"
855                     + "of pool {}", packetHandlingType, config.getDefaultBehavior(), poolName);
856             return;
857         }
858         try {
859             Future<RpcResult<Void>> result = this.idManager.createIdPool(createPool);
860             if ((result != null) && (result.get().isSuccessful())) {
861                 LOG.debug("Created IdPool for {}", poolName);
862             }
863         } catch (InterruptedException | ExecutionException e) {
864             LOG.error("Failed to create ID pool [{}] for ACL flow priority", poolName, e);
865             throw new RuntimeException("Failed to create ID pool for ACL flow priority", e);
866         }
867     }
868
869     /**
870      * Creates the id pool.
871      *
872      * @param poolName the pool name
873      */
874     private void createIdPoolForAclId(String poolName) {
875         CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
876                 .setPoolName(poolName).setLow(AclConstants.ACL_ID_METADATA_POOL_START)
877                 .setHigh(AclConstants.ACL_ID_METADATA_POOL_END).build();
878         try {
879             Future<RpcResult<Void>> result = this.idManager.createIdPool(createPool);
880             if ((result != null) && (result.get().isSuccessful())) {
881                 LOG.debug("Created IdPool for {}", poolName);
882             }
883         } catch (InterruptedException | ExecutionException e) {
884             LOG.error("Failed to create ID pool [{}] for remote ACL ids", poolName, e);
885             throw new RuntimeException("Failed to create ID pool [{}] for remote ACL ids", e);
886         }
887     }
888
889     /**
890      * Delete id pool.
891      *
892      * @param poolName the pool name
893      */
894     public void deleteIdPool(String poolName) {
895         DeleteIdPoolInput deletePool = new DeleteIdPoolInputBuilder().setPoolName(poolName).build();
896         try {
897             Future<RpcResult<Void>> result = this.idManager.deleteIdPool(deletePool);
898             if ((result != null) && (result.get().isSuccessful())) {
899                 LOG.debug("Deleted IdPool for {}", poolName);
900             }
901         } catch (InterruptedException | ExecutionException e) {
902             LOG.error("Failed to delete ID pool [{}]", poolName, e);
903             throw new RuntimeException("Failed to delete ID pool [" + poolName + "]", e);
904         }
905     }
906
907     /**
908      * Gets the acl pool name.
909      *
910      * @param dpId the dp id
911      * @param tableId the table id
912      * @param packetHandlingType packet handling type
913      * @return the acl pool name
914      */
915     public static String getAclPoolName(BigInteger dpId, short tableId,
916                                         AclConstants.PacketHandlingType packetHandlingType) {
917         return AclConstants.ACL_FLOW_PRIORITY_POOL_NAME + "." + dpId + "." + tableId + "." + packetHandlingType;
918     }
919
920     /**
921      * Gets the acl pool name.
922      *
923      * @param dpId the dp id
924      * @param tableId the table id
925      * @param packetHandling packet handling type
926      * @return the acl pool name
927      */
928     public static String getAclPoolName(BigInteger dpId, short tableId, PacketHandling packetHandling) {
929         return packetHandling instanceof Permit
930                 ? getAclPoolName(dpId, tableId, AclConstants.PacketHandlingType.PERMIT)
931                 : getAclPoolName(dpId, tableId, AclConstants.PacketHandlingType.DENY);
932     }
933
934     /**
935      * Creates the acl id pools.
936      *
937      * @param dpId the dp id
938      */
939     public void createAclIdPools(BigInteger dpId) {
940         createIdPool(getAclPoolName(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
941                 AclConstants.PacketHandlingType.PERMIT), AclConstants.PacketHandlingType.PERMIT);
942         createIdPool(getAclPoolName(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
943                 AclConstants.PacketHandlingType.DENY), AclConstants.PacketHandlingType.DENY);
944         createIdPool(getAclPoolName(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
945                 AclConstants.PacketHandlingType.PERMIT), AclConstants.PacketHandlingType.PERMIT);
946         createIdPool(getAclPoolName(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
947                 AclConstants.PacketHandlingType.DENY), AclConstants.PacketHandlingType.DENY);
948     }
949
950     /**
951      * Creates remote the acl id pools.
952      */
953     public void createRemoteAclIdPool() {
954         createIdPoolForAclId(AclConstants.ACL_ID_POOL_NAME);
955     }
956
957     /**
958      * Delete remote the acl id pools.
959      */
960     public void deleteRemoteAclIdPool() {
961         deleteIdPool(AclConstants.ACL_ID_POOL_NAME);
962     }
963
964     /**
965      * Delete acl id pools.
966      *
967      * @param dpId the dp id
968      */
969     public void deleteAclIdPools(BigInteger dpId) {
970         deleteIdPool(getAclPoolName(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
971                 AclConstants.PacketHandlingType.PERMIT));
972         deleteIdPool(getAclPoolName(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
973                 AclConstants.PacketHandlingType.DENY));
974         deleteIdPool(getAclPoolName(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
975                 AclConstants.PacketHandlingType.PERMIT));
976         deleteIdPool(getAclPoolName(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE,
977                 AclConstants.PacketHandlingType.DENY));
978     }
979
980     public static List<? extends MatchInfoBase> buildIpAndSrcServiceMatch(long elanTag, AllowedAddressPairs ip,
981             DataBroker dataBroker, Long vpnId) {
982         List<MatchInfoBase> flowMatches = new ArrayList<>();
983         MatchMetadata metadatMatch = null;
984         if (vpnId == null) {
985             metadatMatch =
986                     new MatchMetadata(MetaDataUtil.getElanTagMetadata(elanTag), MetaDataUtil.METADATA_MASK_SERVICE);
987         } else {
988             metadatMatch =
989                     new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID);
990         }
991         flowMatches.add(metadatMatch);
992         if (ip.getIpAddress().getIpAddress() != null) {
993             if (ip.getIpAddress().getIpAddress().getIpv4Address() != null) {
994                 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
995                 flowMatches.add(ipv4EthMatch);
996                 MatchIpv4Source srcMatch = new MatchIpv4Source(
997                         new Ipv4Prefix(ip.getIpAddress().getIpAddress().getIpv4Address().getValue() + "/32"));
998                 flowMatches.add(srcMatch);
999             } else if (ip.getIpAddress().getIpAddress().getIpv6Address() != null) {
1000                 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1001                 flowMatches.add(ipv6EthMatch);
1002                 MatchIpv6Source srcMatch = new MatchIpv6Source(
1003                         new Ipv6Prefix(ip.getIpAddress().getIpAddress().getIpv6Address().getValue() + "/128"));
1004                 flowMatches.add(srcMatch);
1005             }
1006         } else if (ip.getIpAddress().getIpPrefix() != null) {
1007             if (ip.getIpAddress().getIpPrefix().getIpv4Prefix() != null) {
1008                 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
1009                 flowMatches.add(ipv4EthMatch);
1010                 MatchIpv4Source srcMatch = new MatchIpv4Source(ip.getIpAddress().getIpPrefix().getIpv4Prefix());
1011                 flowMatches.add(srcMatch);
1012             } else if (ip.getIpAddress().getIpPrefix().getIpv6Prefix() != null) {
1013                 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1014                 flowMatches.add(ipv6EthMatch);
1015                 MatchIpv6Source srcMatch = new MatchIpv6Source(ip.getIpAddress().getIpPrefix().getIpv6Prefix());
1016                 flowMatches.add(srcMatch);
1017             }
1018         }
1019         return flowMatches;
1020     }
1021
1022     public static List<? extends MatchInfoBase> buildIpAndDstServiceMatch(Long elanTag, AllowedAddressPairs ip,
1023             DataBroker dataBroker, Long vpnId) {
1024         List<MatchInfoBase> flowMatches = new ArrayList<>();
1025         MatchMetadata metadatMatch = null;
1026         if (vpnId == null) {
1027             metadatMatch =
1028                     new MatchMetadata(MetaDataUtil.getElanTagMetadata(elanTag), MetaDataUtil.METADATA_MASK_SERVICE);
1029         } else {
1030             metadatMatch =
1031                     new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID);
1032         }
1033         flowMatches.add(metadatMatch);
1034
1035         if (ip.getIpAddress().getIpAddress() != null) {
1036             if (ip.getIpAddress().getIpAddress().getIpv4Address() != null) {
1037                 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
1038                 flowMatches.add(ipv4EthMatch);
1039                 MatchIpv4Destination dstMatch = new MatchIpv4Destination(
1040                         new Ipv4Prefix(ip.getIpAddress().getIpAddress().getIpv4Address().getValue() + "/32"));
1041                 flowMatches.add(dstMatch);
1042             } else if (ip.getIpAddress().getIpAddress().getIpv6Address() != null) {
1043                 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1044                 flowMatches.add(ipv6EthMatch);
1045                 MatchIpv6Destination dstMatch = new MatchIpv6Destination(
1046                         new Ipv6Prefix(ip.getIpAddress().getIpAddress().getIpv6Address().getValue() + "/128"));
1047                 flowMatches.add(dstMatch);
1048             }
1049         } else if (ip.getIpAddress().getIpPrefix() != null) {
1050             if (ip.getIpAddress().getIpPrefix().getIpv4Prefix() != null) {
1051                 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
1052                 flowMatches.add(ipv4EthMatch);
1053                 MatchIpv4Destination dstMatch =
1054                         new MatchIpv4Destination(ip.getIpAddress().getIpPrefix().getIpv4Prefix());
1055                 flowMatches.add(dstMatch);
1056             } else if (ip.getIpAddress().getIpPrefix().getIpv6Prefix() != null) {
1057                 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1058                 flowMatches.add(ipv6EthMatch);
1059                 MatchIpv6Destination dstMatch =
1060                         new MatchIpv6Destination(ip.getIpAddress().getIpPrefix().getIpv6Prefix());
1061                 flowMatches.add(dstMatch);
1062             }
1063         }
1064         return flowMatches;
1065     }
1066
1067     public static boolean exactlyOneAcl(AclInterface port) {
1068         return (port.getSecurityGroups() != null) && (port.getSecurityGroups().size() == 1);
1069     }
1070
1071     public static boolean isOfAclInterest(Acl acl) {
1072         List<Ace> aceList = acl.getAccessListEntries().getAce();
1073         if ((aceList != null) && !aceList.isEmpty()) {
1074             return (aceList.get(0).getAugmentation(SecurityRuleAttr.class) != null);
1075         }
1076         return false;
1077     }
1078
1079     public static void addLportTagMetadataMatch(int lportTag, List<MatchInfoBase> flowMatches,
1080             Class<? extends ServiceModeBase> serviceMode) {
1081         MatchInfoBase lportMatch = buildLPortTagMatch(lportTag, serviceMode);
1082         InterfaceServiceUtil.mergeMetadataMatchsOrAdd(flowMatches, lportMatch);
1083     }
1084
1085     static AclInterface buildAclInterfaceState(String interfaceId, InterfaceAcl aclInPort) {
1086         AclInterface aclInterface = new AclInterface();
1087         aclInterface.setInterfaceId(interfaceId);
1088         aclInterface.setPortSecurityEnabled(aclInPort.isPortSecurityEnabled());
1089         aclInterface.setSecurityGroups(aclInPort.getSecurityGroups());
1090         aclInterface.setAllowedAddressPairs(aclInPort.getAllowedAddressPairs());
1091         return aclInterface;
1092     }
1093 }