2 * Copyright (c) 2016, 2018 Red Hat, Inc. and others. All rights reserved.
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
9 package org.opendaylight.netvirt.aclservice.utils;
11 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
12 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
14 import com.google.common.base.Optional;
15 import com.google.common.collect.Lists;
16 import com.google.common.net.InetAddresses;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import java.math.BigInteger;
19 import java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.List;
29 import java.util.Map.Entry;
31 import java.util.SortedSet;
32 import java.util.TreeSet;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.Future;
35 import javax.annotation.Nullable;
36 import javax.inject.Inject;
37 import javax.inject.Singleton;
38 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
39 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
42 import org.opendaylight.genius.infra.Datastore.Operational;
43 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
44 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
45 import org.opendaylight.genius.infra.TypedWriteTransaction;
46 import org.opendaylight.genius.interfacemanager.globals.InterfaceServiceUtil;
47 import org.opendaylight.genius.mdsalutil.ActionInfo;
48 import org.opendaylight.genius.mdsalutil.InstructionInfo;
49 import org.opendaylight.genius.mdsalutil.MDSALUtil;
50 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
51 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
52 import org.opendaylight.genius.mdsalutil.NwConstants;
53 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
54 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
55 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
56 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
57 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
58 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
59 import org.opendaylight.genius.mdsalutil.matches.MatchArpSpa;
60 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination;
61 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
62 import org.opendaylight.genius.mdsalutil.matches.MatchIcmpv6;
63 import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol;
64 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
65 import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Source;
66 import org.opendaylight.genius.mdsalutil.matches.MatchIpv6Destination;
67 import org.opendaylight.genius.mdsalutil.matches.MatchIpv6Source;
68 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
69 import org.opendaylight.genius.mdsalutil.matches.MatchUdpDestinationPort;
70 import org.opendaylight.genius.mdsalutil.matches.MatchUdpSourcePort;
71 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister;
72 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
73 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
74 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
75 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.MatchCriteria;
76 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
77 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AccessLists;
78 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
79 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
80 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
81 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntries;
82 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
83 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches;
84 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
86 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
87 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
88 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
89 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
90 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
93 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
94 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolInput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolInputBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolOutput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.AclPortsLookup;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddressBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionV6;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortSubnets;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.AclPortsByIp;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.AclPortsByIpKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.acl.ports.by.ip.AclIpPrefixes;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.acl.ports.by.ip.AclIpPrefixesKey;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.acl.ports.by.ip.acl.ip.prefixes.PortIds;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.acl.ports.by.ip.acl.ip.prefixes.PortIdsBuilder;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.acl.ports.by.ip.acl.ip.prefixes.PortIdsKey;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnet;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetKey;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.serviceutils.srm.types.rev180626.NetvirtAcl;
153 import org.opendaylight.yangtools.yang.binding.DataObject;
154 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
155 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
156 import org.opendaylight.yangtools.yang.common.RpcResult;
157 import org.slf4j.Logger;
158 import org.slf4j.LoggerFactory;
161 public final class AclServiceUtils {
163 private static final Logger LOG = LoggerFactory.getLogger(AclServiceUtils.class);
164 public static final AclserviceConfig.DefaultBehavior DEFAULT_DENY = AclserviceConfig.DefaultBehavior.Deny;
165 public static final AclserviceConfig.DefaultBehavior DEFAULT_ALLOW = AclserviceConfig.DefaultBehavior.Allow;
167 private final DataBroker dataBroker;
168 private final ManagedNewTransactionRunner txRunner;
169 private final AclDataUtil aclDataUtil;
170 private final AclserviceConfig config;
171 private final IdManagerService idManager;
172 private final JobCoordinator jobCoordinator;
175 public AclServiceUtils(DataBroker dataBroker, AclDataUtil aclDataUtil, AclserviceConfig config,
176 IdManagerService idManager, JobCoordinator jobCoordinator) {
177 this.dataBroker = dataBroker;
178 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
179 this.aclDataUtil = aclDataUtil;
180 this.config = config;
181 this.idManager = idManager;
182 this.jobCoordinator = jobCoordinator;
186 * Retrieves the Interface from the datastore.
187 * @param broker the data broker
188 * @param interfaceName the interface name
189 * @return the interface.
191 public static Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
192 .Interface> getInterface(DataBroker broker, String interfaceName) {
193 return read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
197 * Builds the interface identifier.
198 * @param interfaceName the interface name.
199 * @return the interface identifier.
201 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
202 .interfaces.Interface> getInterfaceIdentifier(String interfaceName) {
203 return InstanceIdentifier.builder(Interfaces.class)
205 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
206 .Interface.class, new InterfaceKey(interfaceName)).build();
210 * Retrieves the object from the datastore.
211 * @param broker the data broker.
212 * @param datastoreType the data store type.
213 * @param path the wild card path.
214 * @param <T> type of DataObject
215 * @return the required object.
217 public static <T extends DataObject> Optional<T> read(
218 DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
219 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
220 return tx.read(datastoreType, path).checkedGet();
221 } catch (ReadFailedException e) {
222 LOG.error("Failed to read InstanceIdentifier {} from {}", path, datastoreType, e);
223 return Optional.absent();
228 * Retrieves the acl matching the key from the data store.
230 * @param broker the data broker
231 * @param aclKey the acl key
234 public static Acl getAcl(DataBroker broker, String aclKey) {
235 return read(broker, LogicalDatastoreType.CONFIGURATION, getAclInstanceIdentifier(aclKey)).orNull();
238 /** Creates the Acl instance identifier.
240 * @param aclKey the acl key
241 * @return the instance identifier
243 public static InstanceIdentifier<Acl> getAclInstanceIdentifier(String aclKey) {
244 return InstanceIdentifier.builder(AccessLists.class).child(Acl.class, new AclKey(aclKey, Ipv4Acl.class))
249 * Get the data path number for the interface.
250 * @param interfaceManagerRpcService interfaceManagerRpcService instance.
251 * @param ifName the interface name.
254 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
255 BigInteger nodeId = BigInteger.ZERO;
257 GetDpidFromInterfaceInput dpIdInput =
258 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
259 Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput =
260 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
261 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
262 if (dpIdResult.isSuccessful()) {
263 nodeId = dpIdResult.getResult().getDpid();
265 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
267 } catch (NullPointerException | InterruptedException | ExecutionException e) {
268 LOG.error("Exception when getting dpn for interface {}", ifName, e);
274 * Retrieves the interface state.
275 * @param dataBroker the data broker.
276 * @param interfaceName the interface name.
277 * @return the interface state.
279 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
280 .Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
281 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
282 .interfaces.state.Interface> ifStateId = buildStateInterfaceId(interfaceName);
283 return MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker).orNull();
287 * Build the interface state.
288 * @param interfaceName the interface name.
289 * @return the interface state.
291 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
292 .interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
293 InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
294 .interfaces.state.Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
295 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
296 .state.Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
297 .rev140508.interfaces.state.InterfaceKey(interfaceName));
298 return idBuilder.build();
302 * Checks whether port security is enabled for the port.
303 * @param port the port.
304 * @return the port security is enabled/not.
306 public static boolean isPortSecurityEnabled(AclInterface port) {
307 return port.isPortSecurityEnabled();
311 * Checks whether port security is enabled for the port.
312 * @param port the port.
313 * @return the list of security groups.
315 public static List<Uuid> getInterfaceAcls(Interface port) {
317 LOG.error("Port is Null");
320 InterfaceAcl aclInPort = port.augmentation(InterfaceAcl.class);
321 if (aclInPort == null) {
322 LOG.error("getSecurityGroupInPortList: no security group associated with port {}",
326 return aclInPort.getSecurityGroups();
330 * Retrieves the security rule attribute augmentation from the access list.
331 * @param ace the access list entry
332 * @return the security rule attributes
334 public static SecurityRuleAttr getAccesssListAttributes(Ace ace) {
336 LOG.error("Ace is Null");
339 SecurityRuleAttr aceAttributes = ace.augmentation(SecurityRuleAttr.class);
340 if (aceAttributes == null) {
341 LOG.error("Ace is null");
344 return aceAttributes;
348 * Returns the DHCP match.
350 * @param srcPort the source port.
351 * @param dstPort the destination port.
352 * @param lportTag the lport tag
353 * @param serviceMode ingress or egress service
354 * @return list of matches.
356 public static List<MatchInfoBase> buildDhcpMatches(int srcPort, int dstPort, int lportTag,
357 Class<? extends ServiceModeBase> serviceMode) {
358 List<MatchInfoBase> matches = new ArrayList<>(5);
359 matches.add(MatchEthernetType.IPV4);
360 matches.add(MatchIpProtocol.UDP);
361 matches.add(new MatchUdpDestinationPort(dstPort));
362 matches.add(new MatchUdpSourcePort(srcPort));
363 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
368 * Returns the DHCPv6 match.
370 * @param srcPort the source port.
371 * @param dstPort the destination port.
372 * @param lportTag the lport tag
373 * @param serviceMode ingress or egress
374 * @return list of matches.
376 public static List<MatchInfoBase> buildDhcpV6Matches(int srcPort, int dstPort, int lportTag,
377 Class<? extends ServiceModeBase> serviceMode) {
378 List<MatchInfoBase> matches = new ArrayList<>(6);
379 matches.add(MatchEthernetType.IPV6);
380 matches.add(MatchIpProtocol.UDP);
381 matches.add(new MatchUdpDestinationPort(dstPort));
382 matches.add(new MatchUdpSourcePort(srcPort));
383 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
388 * Returns the ICMPv6 match.
390 * @param icmpType the icmpv6-type.
391 * @param icmpCode the icmpv6-code.
392 * @param lportTag the lport tag
393 * @param serviceMode ingress or egress
394 * @return list of matches.
396 public static List<MatchInfoBase> buildIcmpV6Matches(int icmpType, int icmpCode, int lportTag,
397 Class<? extends ServiceModeBase> serviceMode) {
398 List<MatchInfoBase> matches = new ArrayList<>();
399 matches.add(MatchEthernetType.IPV6);
400 matches.add(MatchIpProtocol.ICMPV6);
402 matches.add(new MatchIcmpv6((short) icmpType, (short) icmpCode));
404 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
408 public static List<MatchInfoBase> buildBroadcastIpV4Matches(String ipAddr) {
409 List<MatchInfoBase> matches = new ArrayList<>(2);
410 matches.add(new MatchEthernetDestination(new MacAddress(AclConstants.BROADCAST_MAC)));
411 matches.addAll(AclServiceUtils.buildIpMatches(IpPrefixOrAddressBuilder.getDefaultInstance(ipAddr),
412 MatchCriteria.MATCH_DESTINATION));
416 public static List<MatchInfoBase> buildL2BroadcastMatches() {
417 List<MatchInfoBase> matches = new ArrayList<>();
418 matches.add(new MatchEthernetDestination(new MacAddress(AclConstants.BROADCAST_MAC)));
423 * Builds the service id.
425 * @param interfaceName the interface name
426 * @param serviceIndex the service index
427 * @param serviceMode the service mode
428 * @return the instance identifier
430 public static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName, short serviceIndex,
431 Class<? extends ServiceModeBase> serviceMode) {
432 return InstanceIdentifier.builder(ServiceBindings.class)
433 .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
434 .child(BoundServices.class, new BoundServicesKey(serviceIndex)).build();
438 * Gets the bound services.
440 * @param serviceName the service name
441 * @param servicePriority the service priority
442 * @param flowPriority the flow priority
443 * @param cookie the cookie
444 * @param instructions the instructions
445 * @return the bound services
447 public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
448 BigInteger cookie, List<Instruction> instructions) {
449 StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority)
450 .setInstruction(instructions);
451 return new BoundServicesBuilder().withKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
452 .setServicePriority(servicePriority).setServiceType(ServiceTypeFlowBased.class)
453 .addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
456 public static List<Uuid> getUpdatedAclList(List<Uuid> updatedAclList, List<Uuid> currentAclList) {
457 if (updatedAclList == null) {
458 return Collections.emptyList();
460 List<Uuid> newAclList = new ArrayList<>(updatedAclList);
461 if (currentAclList == null) {
464 List<Uuid> origAclList = new ArrayList<>(currentAclList);
465 for (Iterator<Uuid> iterator = newAclList.iterator(); iterator.hasNext();) {
466 Uuid updatedAclUuid = iterator.next();
467 for (Uuid currentAclUuid :origAclList) {
468 if (updatedAclUuid.getValue().equals(currentAclUuid.getValue())) {
476 public static List<AllowedAddressPairs> getUpdatedAllowedAddressPairs(
477 List<AllowedAddressPairs> updatedAllowedAddressPairs,
478 List<AllowedAddressPairs> currentAllowedAddressPairs) {
479 if (updatedAllowedAddressPairs == null) {
482 List<AllowedAddressPairs> newAllowedAddressPairs = new ArrayList<>(updatedAllowedAddressPairs);
483 if (currentAllowedAddressPairs == null) {
484 return newAllowedAddressPairs;
486 List<AllowedAddressPairs> origAllowedAddressPairs = new ArrayList<>(currentAllowedAddressPairs);
487 for (Iterator<AllowedAddressPairs> iterator = newAllowedAddressPairs.iterator(); iterator.hasNext();) {
488 AllowedAddressPairs updatedAllowedAddressPair = iterator.next();
489 for (AllowedAddressPairs currentAllowedAddressPair : origAllowedAddressPairs) {
490 if (updatedAllowedAddressPair.key().equals(currentAllowedAddressPair.key())) {
496 return newAllowedAddressPairs;
499 public static List<AllowedAddressPairs> getPortAllowedAddresses(Interface port) {
501 LOG.error("Port is Null");
504 InterfaceAcl aclInPort = port.augmentation(InterfaceAcl.class);
505 if (aclInPort == null) {
506 LOG.error("getSecurityGroupInPortList: no security group associated to Interface port: {}", port.getName());
509 return aclInPort.getAllowedAddressPairs();
512 public static BigInteger getDpIdFromIterfaceState(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
513 .interfaces.rev140508.interfaces.state.Interface interfaceState) {
514 BigInteger dpId = null;
515 List<String> ofportIds = interfaceState.getLowerLayerIf();
516 if (ofportIds != null && !ofportIds.isEmpty()) {
517 NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
518 dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
523 public static List<String> getIpBroadcastAddresses(List<SubnetInfo> subnetInfoList) {
524 List<String> ipBroadcastAddresses = new ArrayList<>();
525 for (SubnetInfo subnetInfo : subnetInfoList) {
526 IpPrefix cidrIpPrefix = subnetInfo.getIpPrefix().getIpPrefix();
527 if (cidrIpPrefix != null) {
528 Ipv4Prefix cidrIpv4Prefix = cidrIpPrefix.getIpv4Prefix();
529 if (cidrIpv4Prefix != null) {
530 ipBroadcastAddresses.add(getBroadcastAddressFromCidr(cidrIpv4Prefix.getValue()));
534 return ipBroadcastAddresses;
537 public static String getBroadcastAddressFromCidr(String cidr) {
538 String[] ipaddressValues = cidr.split("/");
539 int address = InetAddresses.coerceToInteger(InetAddresses.forString(ipaddressValues[0]));
540 int cidrPart = Integer.parseInt(ipaddressValues[1]);
542 for (int j = 0; j < cidrPart; ++j) {
543 netmask |= 1 << 31 - j;
545 int network = address & netmask;
546 int broadcast = network | ~netmask;
547 return InetAddresses.toAddrString(InetAddresses.fromInteger(broadcast));
551 * Builds the ip matches.
553 * @param ipPrefixOrAddress the ip prefix or address
554 * @param matchCriteria the source_ip or destination_ip used for the match
557 public static List<MatchInfoBase> buildIpMatches(IpPrefixOrAddress ipPrefixOrAddress,
558 MatchCriteria matchCriteria) {
559 List<MatchInfoBase> flowMatches = new ArrayList<>();
560 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
561 if (ipPrefix != null) {
562 Ipv4Prefix ipv4Prefix = ipPrefix.getIpv4Prefix();
563 if (ipv4Prefix != null) {
564 flowMatches.add(MatchEthernetType.IPV4);
565 if (!ipv4Prefix.getValue().equals(AclConstants.IPV4_ALL_NETWORK)) {
566 flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv4Source(ipv4Prefix)
567 : new MatchIpv4Destination(ipv4Prefix));
570 flowMatches.add(MatchEthernetType.IPV6);
571 flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv6Source(
572 ipPrefix.getIpv6Prefix()) : new MatchIpv6Destination(ipPrefix.getIpv6Prefix()));
575 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
576 if (ipAddress.getIpv4Address() != null) {
577 flowMatches.add(MatchEthernetType.IPV4);
578 flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv4Source(
579 ipAddress.getIpv4Address().getValue(), "32") : new MatchIpv4Destination(
580 ipAddress.getIpv4Address().getValue(), "32"));
582 flowMatches.add(MatchEthernetType.IPV6);
583 flowMatches.add(matchCriteria == MatchCriteria.MATCH_SOURCE ? new MatchIpv6Source(
584 ipAddress.getIpv6Address().getValue() + "/128") : new MatchIpv6Destination(
585 ipAddress.getIpv6Address().getValue() + "/128"));
592 * Builds the arp ip matches.
593 * @param ipPrefixOrAddress the ip prefix or address
594 * @return the MatchInfoBase list
596 public static List<MatchInfoBase> buildArpIpMatches(IpPrefixOrAddress ipPrefixOrAddress) {
597 List<MatchInfoBase> flowMatches = new ArrayList<>();
598 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
599 if (ipPrefix != null) {
600 Ipv4Prefix ipv4Prefix = ipPrefix.getIpv4Prefix();
601 if (ipv4Prefix != null && !ipv4Prefix.getValue().equals(AclConstants.IPV4_ALL_NETWORK)) {
602 flowMatches.add(new MatchArpSpa(ipv4Prefix));
605 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
606 if (ipAddress != null && ipAddress.getIpv4Address() != null) {
607 flowMatches.add(new MatchArpSpa(ipAddress.getIpv4Address().getValue(), "32"));
613 public static MatchInfoBase buildRemoteAclTagMetadataMatch(Integer remoteAclTag) {
614 return new MatchMetadata(getRemoteAclTagMetadata(BigInteger.valueOf(remoteAclTag)),
615 MetaDataUtil.METADATA_MASK_REMOTE_ACL_TAG);
618 public static BigInteger getRemoteAclTagMetadata(BigInteger remoteAclTag) {
619 return remoteAclTag.shiftLeft(4);
622 public static BigInteger getDropFlowCookie(int lport) {
623 return MetaDataUtil.getLportTagMetaData(lport).or(AclConstants.COOKIE_ACL_DROP_FLOW);
627 * Does IPv4 address exists in the list of allowed address pair.
629 * @param aaps the allowed address pairs
630 * @return true, if successful
632 public static boolean doesIpv4AddressExists(List<AllowedAddressPairs> aaps) {
636 for (AllowedAddressPairs aap : aaps) {
637 IpPrefixOrAddress ipPrefixOrAddress = aap.getIpAddress();
638 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
639 if (ipPrefix != null) {
640 if (ipPrefix.getIpv4Prefix() != null) {
644 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
645 if (ipAddress != null && ipAddress.getIpv4Address() != null) {
654 * Does IPv6 address exists in the list of allowed address pair.
656 * @param aaps the allowed address pairs
657 * @return true, if successful
659 public static boolean doesIpv6AddressExists(List<AllowedAddressPairs> aaps) {
663 for (AllowedAddressPairs aap : aaps) {
664 IpPrefixOrAddress ipPrefixOrAddress = aap.getIpAddress();
665 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
666 if (ipPrefix != null) {
667 if (ipPrefix.getIpv6Prefix() != null) {
671 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
672 if (ipAddress != null && ipAddress.getIpv6Address() != null) {
681 * Gets the lport tag match.
682 * Ingress match is based on metadata and egress match is based on masked reg6
684 * @param lportTag the lport tag
685 * @param serviceMode ingress or egress service mode
686 * @return the lport tag match
688 public static MatchInfoBase buildLPortTagMatch(int lportTag, Class<? extends ServiceModeBase> serviceMode) {
689 if (serviceMode != null && serviceMode.isAssignableFrom(ServiceModeEgress.class)) {
690 return new NxMatchRegister(NxmNxReg6.class, MetaDataUtil.getLportTagForReg6(lportTag).longValue(),
691 MetaDataUtil.getLportTagMaskForReg6());
693 return new MatchMetadata(MetaDataUtil.getLportTagMetaData(lportTag), MetaDataUtil.METADATA_MASK_LPORT_TAG);
697 public static List<MatchInfoBase> buildMatchesForLPortTagAndRemoteAclTag(Integer lportTag, Integer remoteAclTag,
698 Class<? extends ServiceModeBase> serviceMode) {
699 List<MatchInfoBase> matches = new ArrayList<>();
700 if (serviceMode != null && serviceMode.isAssignableFrom(ServiceModeEgress.class)) {
701 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
702 matches.add(AclServiceUtils.buildRemoteAclTagMetadataMatch(remoteAclTag));
704 // In case of ingress service mode, only metadata is used for
705 // matching both lportTag and aclTag. Hence performing "or"
706 // operation on both lportTag and aclTag metadata.
707 BigInteger metaData = MetaDataUtil.getLportTagMetaData(lportTag)
708 .or(getRemoteAclTagMetadata(BigInteger.valueOf(remoteAclTag)));
709 BigInteger metaDataMask =
710 MetaDataUtil.METADATA_MASK_LPORT_TAG.or(MetaDataUtil.METADATA_MASK_REMOTE_ACL_TAG);
711 matches.add(new MatchMetadata(metaData, metaDataMask));
716 public static Collection<? extends MatchInfoBase> buildMatchesForLPortTagAndConntrackClassifierType(int lportTag,
717 AclConntrackClassifierType conntrackClassifierType, Class<? extends ServiceModeBase> serviceMode) {
718 List<MatchInfoBase> matches = new ArrayList<>();
719 if (serviceMode != null && serviceMode.isAssignableFrom(ServiceModeEgress.class)) {
720 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
721 matches.add(AclServiceUtils.buildAclConntrackClassifierTypeMatch(conntrackClassifierType));
723 // In case of ingress service mode, only metadata is used for
724 // matching both lportTag and conntrackClassifierType. Hence performing "or"
725 // operation on both lportTag and conntrackClassifierType metadata.
726 BigInteger metaData = MetaDataUtil.getLportTagMetaData(lportTag)
727 .or(MetaDataUtil.getAclConntrackClassifierTypeFromMetaData(conntrackClassifierType.getValue()));
728 BigInteger metaDataMask =
729 MetaDataUtil.METADATA_MASK_LPORT_TAG.or(MetaDataUtil.METADATA_MASK_ACL_CONNTRACK_CLASSIFIER_TYPE);
730 matches.add(new MatchMetadata(metaData, metaDataMask));
735 public static InstructionWriteMetadata getWriteMetadataForAclClassifierType(
736 AclConntrackClassifierType conntrackClassifierType) {
737 return new InstructionWriteMetadata(
738 MetaDataUtil.getAclConntrackClassifierTypeFromMetaData(conntrackClassifierType.getValue()),
739 MetaDataUtil.METADATA_MASK_ACL_CONNTRACK_CLASSIFIER_TYPE);
742 public static InstructionWriteMetadata getWriteMetadataForDropFlag() {
743 return new InstructionWriteMetadata(MetaDataUtil.getAclDropMetaData(AclConstants.METADATA_DROP_FLAG),
744 MetaDataUtil.METADATA_MASK_ACL_DROP);
747 public static InstructionWriteMetadata getWriteMetadataForRemoteAclTag(Integer remoteAclTag) {
748 return new InstructionWriteMetadata(getRemoteAclTagMetadata(BigInteger.valueOf(remoteAclTag)),
749 MetaDataUtil.METADATA_MASK_REMOTE_ACL_TAG);
752 public static MatchInfoBase buildAclConntrackClassifierTypeMatch(
753 AclConntrackClassifierType conntrackSupportedType) {
754 return new MatchMetadata(
755 MetaDataUtil.getAclConntrackClassifierTypeFromMetaData(conntrackSupportedType.getValue()),
756 MetaDataUtil.METADATA_MASK_ACL_CONNTRACK_CLASSIFIER_TYPE);
759 public AclserviceConfig getConfig() {
763 public static boolean isIPv4Address(AllowedAddressPairs aap) {
764 IpPrefixOrAddress ipPrefixOrAddress = aap.getIpAddress();
765 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
766 if (ipPrefix != null) {
767 if (ipPrefix.getIpv4Prefix() != null) {
771 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
772 if (ipAddress != null && ipAddress.getIpv4Address() != null) {
779 public static Map<String, List<MatchInfoBase>> getFlowForAllowedAddresses(
780 List<AllowedAddressPairs> syncAllowedAddresses, Map<String, List<MatchInfoBase>> flowMatchesMap,
781 boolean isSourceIpMacMatch) {
782 if (flowMatchesMap == null) {
785 Map<String, List<MatchInfoBase>> updatedFlowMatchesMap = new HashMap<>();
786 MatchInfoBase ipv4Match = MatchEthernetType.IPV4;
787 MatchInfoBase ipv6Match = MatchEthernetType.IPV6;
788 for (Entry<String, List<MatchInfoBase>> entry : flowMatchesMap.entrySet()) {
789 String flowName = entry.getKey();
790 List<MatchInfoBase> flows = entry.getValue();
791 // iterate over allow address pair and update match type
792 for (AllowedAddressPairs aap : syncAllowedAddresses) {
793 List<MatchInfoBase> matchInfoBaseList;
795 if (flows.contains(ipv4Match) && isIPv4Address(aap) && isNotIpv4AllNetwork(aap)) {
796 matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
797 flowId = flowName + "_ipv4_remoteACL_interface_aap_" + getAapFlowId(aap);
798 updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
799 } else if (flows.contains(ipv6Match) && !isIPv4Address(aap) && isNotIpv6AllNetwork(aap)) {
800 matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
801 flowId = flowName + "_ipv6_remoteACL_interface_aap_" + getAapFlowId(aap);
802 updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
806 return updatedFlowMatchesMap;
809 public static boolean isNotIpv4AllNetwork(AllowedAddressPairs aap) {
810 IpPrefix ipPrefix = aap.getIpAddress().getIpPrefix();
811 if (ipPrefix != null && ipPrefix.getIpv4Prefix() != null
812 && ipPrefix.getIpv4Prefix().getValue().equals(AclConstants.IPV4_ALL_NETWORK)) {
818 protected static boolean isNotIpv6AllNetwork(AllowedAddressPairs aap) {
819 IpPrefix ipPrefix = aap.getIpAddress().getIpPrefix();
820 if (ipPrefix != null && ipPrefix.getIpv6Prefix() != null
821 && ipPrefix.getIpv6Prefix().getValue().equals(AclConstants.IPV6_ALL_NETWORK)) {
827 public static boolean isNotIpAllNetwork(AllowedAddressPairs aap) {
828 return isNotIpv4AllNetwork(aap) && isNotIpv6AllNetwork(aap);
831 private static String getAapFlowId(AllowedAddressPairs aap) {
832 return aap.getMacAddress().getValue() + "_" + aap.getIpAddress().stringValue();
835 public static Long getElanIdFromInterface(String elanInterfaceName,DataBroker broker) {
836 ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(elanInterfaceName, broker);
837 if (null != elanInterface) {
838 ElanInstance elanInfo = getElanInstanceByName(elanInterface.getElanInstanceName(), broker);
839 return elanInfo.getElanTag();
844 public static ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName,DataBroker broker) {
845 InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
846 return read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull();
849 public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
850 return InstanceIdentifier.builder(ElanInterfaces.class)
851 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
854 // elan-instances config container
855 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
856 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
857 return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
860 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
861 return InstanceIdentifier.builder(ElanInstances.class)
862 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
865 public List<SubnetInfo> getSubnetInfo(String portId) {
866 InstanceIdentifier<PortSubnet> id = InstanceIdentifier.builder(PortSubnets.class)
867 .child(PortSubnet.class, new PortSubnetKey(portId)).build();
869 Optional<PortSubnet> portSubnet = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
870 if (portSubnet.isPresent()) {
871 return portSubnet.get().getSubnetInfo();
876 public void deleteSubnetInfo(String portId) {
877 InstanceIdentifier<PortSubnet> id = InstanceIdentifier.builder(PortSubnets.class)
878 .child(PortSubnet.class, new PortSubnetKey(portId)).build();
879 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
880 OPERATIONAL, tx -> tx.delete(id)), LOG, "Failed to delete subnet info for port: " + portId);
883 private static List<MatchInfoBase> updateAAPMatches(boolean isSourceIpMacMatch, List<MatchInfoBase> flows,
884 AllowedAddressPairs aap) {
885 List<MatchInfoBase> matchInfoBaseList;
886 if (isSourceIpMacMatch) {
887 matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchCriteria.MATCH_SOURCE);
889 matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchCriteria.MATCH_DESTINATION);
891 matchInfoBaseList.addAll(flows);
892 return matchInfoBaseList;
895 public static MatchInfoBase getMatchInfoByType(List<MatchInfoBase> flows, Class<? extends NxMatchInfo> type) {
896 for (MatchInfoBase mib : flows) {
897 if (type.isAssignableFrom(mib.getClass())) {
904 public static boolean containsMatchFieldType(List<MatchInfoBase> flows, Class<? extends NxMatchInfo> type) {
905 return getMatchInfoByType(flows, type) != null;
908 public static boolean containsTcpMatchField(List<MatchInfoBase> flows) {
909 return flows.contains(MatchIpProtocol.TCP);
912 public static boolean containsUdpMatchField(List<MatchInfoBase> flows) {
913 return flows.contains(MatchIpProtocol.UDP);
916 public static Integer allocateId(IdManagerService idManager, String poolName, String idKey, Integer defaultId) {
917 AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
919 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
920 RpcResult<AllocateIdOutput> rpcResult = result.get();
921 if (rpcResult.isSuccessful()) {
922 Integer allocatedId = rpcResult.getResult().getIdValue().intValue();
923 LOG.debug("Allocated ACL ID: {} with key: {} into pool: {}", allocatedId, idKey, poolName);
926 LOG.error("RPC Call to Get Unique Id for key {} from pool {} returned with Errors {}",
927 idKey, poolName, rpcResult.getErrors());
929 } catch (InterruptedException | ExecutionException e) {
930 LOG.error("Exception when getting Unique Id for key {} from pool {} ", idKey, poolName, e);
935 public static void releaseId(IdManagerService idManager, String poolName, String idKey) {
936 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
938 RpcResult<ReleaseIdOutput> rpcResult = idManager.releaseId(idInput).get();
939 if (!rpcResult.isSuccessful()) {
940 LOG.error("RPC Call to release Id with Key {} from pool {} returned with Errors {}",
941 idKey, poolName, rpcResult.getErrors());
943 LOG.debug("Released ACL ID with key: {} from pool: {}", idKey, poolName);
945 } catch (InterruptedException | ExecutionException e) {
946 LOG.error("Exception when releasing Id for key {} from pool {} ", idKey, poolName, e);
951 * Gets the ACL tag from cache. If not found in cache, tries to allocate and
954 * @param aclId the acl id
955 * @return the acl tag
957 public Integer getAclTag(final Uuid aclId) {
958 String aclName = aclId.getValue();
959 Integer aclTag = this.aclDataUtil.getAclTag(aclName);
960 if (aclTag == null) {
961 LOG.debug("ACL tag not found in cache for ACL={}, trying to allocate again.", aclName);
962 aclTag = allocateAclTag(aclName);
963 if (aclTag != null && aclTag != AclConstants.INVALID_ACL_TAG) {
964 this.aclDataUtil.addAclTag(aclName, aclTag);
973 * @param aclName the ACL name
974 * @return the integer
976 public Integer allocateAclTag(String aclName) {
977 return AclServiceUtils.allocateId(this.idManager, AclConstants.ACL_TAG_POOL_NAME, aclName,
978 AclConstants.INVALID_ACL_TAG);
984 * @param aclName the ACL name
986 public void releaseAclTag(String aclName) {
987 AclServiceUtils.releaseId(this.idManager, AclConstants.ACL_TAG_POOL_NAME, aclName);
991 * Indicates whether the interface has port security enabled.
993 * @param aclInterface the interface.
994 * @return true if port is security enabled.
996 public static boolean isOfInterest(AclInterface aclInterface) {
997 return aclInterface != null && aclInterface.isPortSecurityEnabled();
1001 * Creates the id pool for ACL tag.
1003 * @param poolName the pool name
1005 private void createIdPoolForAclTag(String poolName) {
1006 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
1007 .setPoolName(poolName).setLow(AclConstants.ACL_TAG_POOL_START)
1008 .setHigh(AclConstants.ACL_TAG_POOL_END).build();
1010 Future<RpcResult<CreateIdPoolOutput>> result = this.idManager.createIdPool(createPool);
1011 if (result != null && result.get().isSuccessful()) {
1012 LOG.debug("Created IdPool for {}", poolName);
1014 } catch (InterruptedException | ExecutionException e) {
1015 LOG.error("Failed to create ID pool [{}] for remote ACL ids", poolName, e);
1016 throw new RuntimeException("Failed to create ID pool [{}] for remote ACL ids", e);
1023 * @param poolName the pool name
1025 public void deleteIdPool(String poolName) {
1026 DeleteIdPoolInput deletePool = new DeleteIdPoolInputBuilder().setPoolName(poolName).build();
1028 Future<RpcResult<DeleteIdPoolOutput>> result = this.idManager.deleteIdPool(deletePool);
1029 if (result != null && result.get().isSuccessful()) {
1030 LOG.debug("Deleted IdPool for {}", poolName);
1032 } catch (InterruptedException | ExecutionException e) {
1033 LOG.error("Failed to delete ID pool [{}]", poolName, e);
1034 throw new RuntimeException("Failed to delete ID pool [" + poolName + "]", e);
1039 * Creates remote the acl id pools.
1041 public void createRemoteAclIdPool() {
1042 createIdPoolForAclTag(AclConstants.ACL_TAG_POOL_NAME);
1046 * Delete remote the acl id pools.
1048 public void deleteRemoteAclIdPool() {
1049 deleteIdPool(AclConstants.ACL_TAG_POOL_NAME);
1052 public static List<? extends MatchInfoBase> buildIpAndSrcServiceMatch(Integer aclTag, AllowedAddressPairs aap) {
1053 List<MatchInfoBase> flowMatches = new ArrayList<>();
1054 flowMatches.add(buildRemoteAclTagMetadataMatch(aclTag));
1055 if (aap.getIpAddress().getIpAddress() != null) {
1056 if (aap.getIpAddress().getIpAddress().getIpv4Address() != null) {
1057 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
1058 flowMatches.add(ipv4EthMatch);
1059 MatchIpv4Source srcMatch = new MatchIpv4Source(
1060 new Ipv4Prefix(aap.getIpAddress().getIpAddress().getIpv4Address().getValue() + "/32"));
1061 flowMatches.add(srcMatch);
1062 } else if (aap.getIpAddress().getIpAddress().getIpv6Address() != null) {
1063 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1064 flowMatches.add(ipv6EthMatch);
1065 MatchIpv6Source srcMatch = new MatchIpv6Source(
1066 new Ipv6Prefix(aap.getIpAddress().getIpAddress().getIpv6Address().getValue() + "/128"));
1067 flowMatches.add(srcMatch);
1069 } else if (aap.getIpAddress().getIpPrefix() != null) {
1070 if (aap.getIpAddress().getIpPrefix().getIpv4Prefix() != null) {
1071 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
1072 flowMatches.add(ipv4EthMatch);
1073 MatchIpv4Source srcMatch = new MatchIpv4Source(aap.getIpAddress().getIpPrefix().getIpv4Prefix());
1074 flowMatches.add(srcMatch);
1075 } else if (aap.getIpAddress().getIpPrefix().getIpv6Prefix() != null) {
1076 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1077 flowMatches.add(ipv6EthMatch);
1078 MatchIpv6Source srcMatch = new MatchIpv6Source(aap.getIpAddress().getIpPrefix().getIpv6Prefix());
1079 flowMatches.add(srcMatch);
1085 public static List<? extends MatchInfoBase> buildIpAndDstServiceMatch(Integer aclTag, AllowedAddressPairs aap) {
1086 List<MatchInfoBase> flowMatches = new ArrayList<>();
1087 flowMatches.add(buildRemoteAclTagMetadataMatch(aclTag));
1089 if (aap.getIpAddress().getIpAddress() != null) {
1090 if (aap.getIpAddress().getIpAddress().getIpv4Address() != null) {
1091 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
1092 flowMatches.add(ipv4EthMatch);
1093 MatchIpv4Destination dstMatch = new MatchIpv4Destination(
1094 new Ipv4Prefix(aap.getIpAddress().getIpAddress().getIpv4Address().getValue() + "/32"));
1095 flowMatches.add(dstMatch);
1096 } else if (aap.getIpAddress().getIpAddress().getIpv6Address() != null) {
1097 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1098 flowMatches.add(ipv6EthMatch);
1099 MatchIpv6Destination dstMatch = new MatchIpv6Destination(
1100 new Ipv6Prefix(aap.getIpAddress().getIpAddress().getIpv6Address().getValue() + "/128"));
1101 flowMatches.add(dstMatch);
1103 } else if (aap.getIpAddress().getIpPrefix() != null) {
1104 if (aap.getIpAddress().getIpPrefix().getIpv4Prefix() != null) {
1105 MatchEthernetType ipv4EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV4);
1106 flowMatches.add(ipv4EthMatch);
1107 MatchIpv4Destination dstMatch =
1108 new MatchIpv4Destination(aap.getIpAddress().getIpPrefix().getIpv4Prefix());
1109 flowMatches.add(dstMatch);
1110 } else if (aap.getIpAddress().getIpPrefix().getIpv6Prefix() != null) {
1111 MatchEthernetType ipv6EthMatch = new MatchEthernetType(NwConstants.ETHTYPE_IPV6);
1112 flowMatches.add(ipv6EthMatch);
1113 MatchIpv6Destination dstMatch =
1114 new MatchIpv6Destination(aap.getIpAddress().getIpPrefix().getIpv6Prefix());
1115 flowMatches.add(dstMatch);
1121 public static boolean isOfAclInterest(Acl acl) {
1122 if (acl.getAccessListEntries() != null) {
1123 List<Ace> aceList = acl.getAccessListEntries().getAce();
1124 if (aceList != null && !aceList.isEmpty()) {
1125 return aceList.get(0).augmentation(SecurityRuleAttr.class) != null;
1131 public static void addLportTagMetadataMatch(int lportTag, List<MatchInfoBase> flowMatches,
1132 Class<? extends ServiceModeBase> serviceMode) {
1133 MatchInfoBase lportMatch = buildLPortTagMatch(lportTag, serviceMode);
1134 InterfaceServiceUtil.mergeMetadataMatchsOrAdd(flowMatches, lportMatch);
1138 * Returns ACL specific key for synchronization.
1140 * @param key the generic key
1141 * @return ACL key that can be used with synchronization
1143 public static String getAclKeyForSynchronization(String key) {
1144 return key + AclConstants.ACL_SYNC_KEY_EXT;
1148 * Builds the ip protocol matches.
1150 * @param etherType the ether type
1151 * @param protocol the protocol
1152 * @return the list of matches.
1154 public static List<MatchInfoBase> buildIpProtocolMatches(MatchEthernetType etherType, IPProtocols protocol) {
1155 return Lists.newArrayList(etherType, new MatchIpProtocol(protocol.shortValue()));
1159 * Does ACE have remote group id.
1161 * @param aceAttr the ace attr
1162 * @return true, if successful
1164 public static boolean doesAceHaveRemoteGroupId(final SecurityRuleAttr aceAttr) {
1165 return aceAttr != null && aceAttr.getRemoteGroupId() != null;
1168 public SortedSet<Integer> getRemoteAclTags(List<Uuid> aclIds, Class<? extends DirectionBase> direction) {
1169 SortedSet<Integer> remoteAclTags = new TreeSet<>();
1170 Set<Uuid> remoteAclIds = getRemoteAclIdsByDirection(aclIds, direction);
1171 for (Uuid remoteAclId : remoteAclIds) {
1172 Integer remoteAclTag = getAclTag(remoteAclId);
1173 if (remoteAclTag != null && remoteAclTag != AclConstants.INVALID_ACL_TAG) {
1174 remoteAclTags.add(remoteAclTag);
1177 return remoteAclTags;
1180 public Set<Uuid> getRemoteAclIdsByDirection(List<Uuid> aclIds, Class<? extends DirectionBase> direction) {
1181 Set<Uuid> remoteAclIds = new HashSet<>();
1182 if (aclIds == null || aclIds.isEmpty()) {
1183 return remoteAclIds;
1186 for (Uuid aclId : aclIds) {
1187 Acl acl = this.aclDataUtil.getAcl(aclId.getValue());
1189 LOG.warn("ACL {} not found in cache.", aclId.getValue());
1192 remoteAclIds.addAll(getRemoteAclIdsByDirection(acl, direction));
1194 return remoteAclIds;
1197 public static Set<Uuid> getRemoteAclIdsByDirection(Acl acl, Class<? extends DirectionBase> direction) {
1198 Set<Uuid> remoteAclIds = new HashSet<>();
1199 AccessListEntries accessListEntries = acl.getAccessListEntries();
1200 if (accessListEntries != null && accessListEntries.getAce() != null) {
1201 for (Ace ace : accessListEntries.getAce()) {
1202 SecurityRuleAttr aceAttr = AclServiceUtils.getAccesssListAttributes(ace);
1203 if (aceAttr.getDirection().equals(direction) && doesAceHaveRemoteGroupId(aceAttr)) {
1204 remoteAclIds.add(aceAttr.getRemoteGroupId());
1208 return remoteAclIds;
1212 * Skip delete in case of overlapping IP.
1215 * When there are multiple ports (e.g., p1, p2, p3) having same AAP (e.g.,
1216 * 224.0.0.5) configured which are part of single SG, there would be single
1217 * flow in remote ACL table. When one of these ports (say p1) is deleted,
1218 * the single flow which is configured in remote ACL table shouldn't be
1219 * deleted. It should be deleted only when there are no more references to
1222 * @param portId the port id
1223 * @param remoteAclId the remote Acl Id
1224 * @param ipPrefix the ip prefix
1225 * @param addOrRemove the add or remove
1226 * @return true, if successful
1228 public boolean skipDeleteInCaseOfOverlappingIP(String portId, Uuid remoteAclId, IpPrefixOrAddress ipPrefix,
1230 boolean skipDelete = false;
1231 if (addOrRemove != NwConstants.DEL_FLOW) {
1234 AclIpPrefixes aclIpPrefixes = getAclIpPrefixesFromOperDs(remoteAclId.getValue(), ipPrefix);
1235 if (aclIpPrefixes != null && aclIpPrefixes.getPortIds() != null) {
1236 List<String> ignorePorts = Lists.newArrayList(portId);
1237 List<PortIds> portIds = new ArrayList<>(aclIpPrefixes.getPortIds());
1238 // Checking if there are any other ports excluding ignorePorts
1239 long noOfRemotePorts =
1240 portIds.stream().map(PortIds::getPortId).filter(y -> !ignorePorts.contains(y)).count();
1241 if (noOfRemotePorts > 0) {
1248 public static InstanceIdentifier<AclPortsByIp> aclPortsByIpPath(String aclName) {
1249 return InstanceIdentifier.builder(AclPortsLookup.class)
1250 .child(AclPortsByIp.class, new AclPortsByIpKey(aclName)).build();
1253 public static InstanceIdentifier<AclIpPrefixes> getAclIpPrefixesPath(String aclName, IpPrefixOrAddress ipPrefix) {
1254 return InstanceIdentifier.builder(AclPortsLookup.class).child(AclPortsByIp.class, new AclPortsByIpKey(aclName))
1255 .child(AclIpPrefixes.class, new AclIpPrefixesKey(ipPrefix)).build();
1258 public static InstanceIdentifier<PortIds> getPortIdsPathInAclPortsLookup(String ruleName,
1259 IpPrefixOrAddress ipPrefix, String portId) {
1260 return InstanceIdentifier.builder(AclPortsLookup.class).child(AclPortsByIp.class, new AclPortsByIpKey(ruleName))
1261 .child(AclIpPrefixes.class, new AclIpPrefixesKey(ipPrefix)).child(PortIds.class, new PortIdsKey(portId))
1265 public void addAclPortsLookupForInterfaceUpdate(AclInterface portBefore, AclInterface portAfter) {
1266 LOG.debug("Processing interface additions for port {}", portAfter.getInterfaceId());
1267 List<AllowedAddressPairs> addedAllowedAddressPairs = getUpdatedAllowedAddressPairs(
1268 portAfter.getAllowedAddressPairs(), portBefore.getAllowedAddressPairs());
1269 if (addedAllowedAddressPairs != null && !addedAllowedAddressPairs.isEmpty()) {
1270 addAclPortsLookup(portAfter, portAfter.getSecurityGroups(), addedAllowedAddressPairs);
1273 List<Uuid> addedAcls = getUpdatedAclList(portAfter.getSecurityGroups(), portBefore.getSecurityGroups());
1274 if (addedAcls != null && !addedAcls.isEmpty()) {
1275 addAclPortsLookup(portAfter, addedAcls, portAfter.getAllowedAddressPairs());
1279 public void deleteAclPortsLookupForInterfaceUpdate(AclInterface portBefore, AclInterface portAfter) {
1280 LOG.debug("Processing interface removals for port {}", portAfter.getInterfaceId());
1281 List<AllowedAddressPairs> deletedAllowedAddressPairs = getUpdatedAllowedAddressPairs(
1282 portBefore.getAllowedAddressPairs(), portAfter.getAllowedAddressPairs());
1283 if (deletedAllowedAddressPairs != null && !deletedAllowedAddressPairs.isEmpty()) {
1284 deleteAclPortsLookup(portAfter, portAfter.getSecurityGroups(), deletedAllowedAddressPairs);
1287 List<Uuid> deletedAcls = getUpdatedAclList(portBefore.getSecurityGroups(), portAfter.getSecurityGroups());
1288 if (deletedAcls != null && !deletedAcls.isEmpty()) {
1289 deleteAclPortsLookup(portAfter, deletedAcls, portAfter.getAllowedAddressPairs());
1293 public void addAclPortsLookup(AclInterface port, List<Uuid> aclList,
1294 List<AllowedAddressPairs> allowedAddresses) {
1295 String portId = port.getInterfaceId();
1296 LOG.trace("Adding AclPortsLookup for port={}, acls={}, AAPs={}", portId, aclList, allowedAddresses);
1298 if (aclList == null || allowedAddresses == null || allowedAddresses.isEmpty()) {
1299 LOG.warn("aclList or allowedAddresses is null. port={}, acls={}, AAPs={}", portId, aclList,
1304 for (Uuid aclId : aclList) {
1305 String aclName = aclId.getValue();
1306 jobCoordinator.enqueueJob(aclName.intern(), () -> {
1307 List<ListenableFuture<Void>> futures = new ArrayList<>();
1308 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
1309 for (AllowedAddressPairs aap : allowedAddresses) {
1311 new PortIdsBuilder().withKey(new PortIdsKey(portId)).setPortId(portId).build();
1312 InstanceIdentifier<PortIds> path =
1313 AclServiceUtils.getPortIdsPathInAclPortsLookup(aclName, aap.getIpAddress(), portId);
1314 tx.put(path, portIdObj, CREATE_MISSING_PARENTS);
1322 public void deleteAclPortsLookup(AclInterface port, List<Uuid> aclList,
1323 List<AllowedAddressPairs> allowedAddresses) {
1324 String portId = port.getInterfaceId();
1325 LOG.trace("Deleting AclPortsLookup for port={}, acls={}, AAPs={}", portId, aclList, allowedAddresses);
1327 if (aclList == null || allowedAddresses == null || allowedAddresses.isEmpty()) {
1328 LOG.warn("aclList or allowedAddresses is null. port={}, acls={}, AAPs={}", portId, aclList,
1333 for (Uuid aclId : aclList) {
1334 String aclName = aclId.getValue();
1335 jobCoordinator.enqueueJob(aclName.intern(), () -> {
1336 List<ListenableFuture<Void>> futures = new ArrayList<>();
1337 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
1338 for (AllowedAddressPairs aap : allowedAddresses) {
1339 InstanceIdentifier<PortIds> path =
1340 AclServiceUtils.getPortIdsPathInAclPortsLookup(aclName, aap.getIpAddress(), portId);
1344 cleanUpStaleEntriesInAclPortsLookup(aclName, tx);
1351 private void cleanUpStaleEntriesInAclPortsLookup(String aclName, TypedWriteTransaction<Operational> tx) {
1352 AclPortsByIp aclPortsByIp = getAclPortsByIpFromOperDs(aclName);
1353 if (aclPortsByIp == null) {
1356 boolean deleteEntireAcl;
1357 List<AclIpPrefixes> ipPrefixes = aclPortsByIp.getAclIpPrefixes();
1358 if (ipPrefixes == null || ipPrefixes.isEmpty()) {
1359 deleteEntireAcl = true;
1361 boolean deleteMap = true;
1362 for (AclIpPrefixes ipPrefix : ipPrefixes) {
1363 if (ipPrefix.getPortIds() != null && !ipPrefix.getPortIds().isEmpty()) {
1368 deleteEntireAcl = deleteMap;
1370 if (deleteEntireAcl) {
1371 tx.delete(AclServiceUtils.aclPortsByIpPath(aclName));
1373 for (AclIpPrefixes ipPrefix : ipPrefixes) {
1374 if (ipPrefix.getPortIds() == null || ipPrefix.getPortIds().isEmpty()) {
1375 InstanceIdentifier<AclIpPrefixes> delPath =
1376 AclServiceUtils.getAclIpPrefixesPath(aclName, ipPrefix.getIpPrefix());
1384 private AclPortsByIp getAclPortsByIpFromOperDs(String aclName) {
1385 InstanceIdentifier<AclPortsByIp> path = aclPortsByIpPath(aclName);
1386 try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) {
1387 return tx.read(LogicalDatastoreType.OPERATIONAL, path).checkedGet().orNull();
1388 } catch (ReadFailedException e) {
1389 LOG.error("Failed to read ACL ports {}", path, e);
1395 private AclIpPrefixes getAclIpPrefixesFromOperDs(String aclName, IpPrefixOrAddress ipPrefix) {
1396 InstanceIdentifier<AclIpPrefixes> path = getAclIpPrefixesPath(aclName, ipPrefix);
1397 try (ReadOnlyTransaction tx = dataBroker.newReadOnlyTransaction()) {
1398 return tx.read(LogicalDatastoreType.OPERATIONAL, path).checkedGet().orNull();
1399 } catch (ReadFailedException e) {
1400 LOG.error("Failed to read ACL IP prefixes {}", path, e);
1406 * Gets the ace flow priority.
1408 * @param aclName the acl name
1409 * @return the ace flow priority
1411 public Integer getAceFlowPriority(String aclName) {
1412 Integer priority = AclConstants.ACE_DEFAULT_PRIORITY;
1413 Integer aclTag = getAclTag(new Uuid(aclName));
1414 if (aclTag != null && aclTag != AclConstants.INVALID_ACL_TAG) {
1415 // To handle overlapping rules, aclTag is added to priority
1418 LOG.warn("aclTag={} is null or invalid for aclName={}", aclTag, aclName);
1424 * Returns the hard timeout based on the protocol when a ACL rule removed from the instance.
1425 * It will returns the timeout configured in the {@link AclserviceConfig} class.
1427 * @param ace the ace
1428 * @param aclServiceUtils acl service utils
1429 * @return the hard time out
1431 public static Integer getHardTimoutForApplyStatefulChangeOnExistingTraffic(Ace ace,
1432 AclServiceUtils aclServiceUtils) {
1433 int hardTimeout = AclConstants.SECURITY_GROUP_ICMP_IDLE_TIME_OUT;
1434 Matches matches = ace.getMatches();
1435 AceIp acl = (AceIp) matches.getAceType();
1436 Short protocol = acl.getProtocol();
1437 if (protocol == null) {
1439 } else if (protocol == NwConstants.IP_PROT_TCP) {
1440 hardTimeout = aclServiceUtils.getConfig().getSecurityGroupTcpIdleTimeout();
1441 } else if (protocol == NwConstants.IP_PROT_UDP) {
1442 hardTimeout = aclServiceUtils.getConfig().getSecurityGroupUdpIdleTimeout();
1448 * This method creates and returns the ct_mark instruction when a ACL rule removed from the
1449 * instance. This instruction will reset the ct_mark value and stops the existing traffics.
1451 * @param filterTable the filterTable
1452 * @param elanId the Elan id
1453 * @return list of instruction
1455 public static List<InstructionInfo> createCtMarkInstructionForNewState(Short filterTable, Long elanId) {
1457 List<InstructionInfo> instructions = new ArrayList<>();
1458 List<ActionInfo> actionsInfos = new ArrayList<>();
1459 List<NxCtAction> ctActionsList = new ArrayList<>();
1460 NxCtAction nxCtMarkClearAction = new ActionNxConntrack.NxCtMark(AclConstants.CT_MARK_NEW_STATE);
1461 ctActionsList.add(nxCtMarkClearAction);
1463 ActionNxConntrack actionNxConntrack = new ActionNxConntrack(2, 1, 0, elanId.intValue(),
1464 (short) 255, ctActionsList);
1465 actionsInfos.add(actionNxConntrack);
1466 instructions.add(new InstructionApplyActions(actionsInfos));
1467 instructions.add(new InstructionGotoTable(filterTable));
1469 return instructions;
1472 public static List<AllowedAddressPairs> excludeMulticastAAPs(List<AllowedAddressPairs> allowedAddresses) {
1473 List<AllowedAddressPairs> filteredAAPs = new ArrayList<>();
1474 for (AllowedAddressPairs allowedAddress : allowedAddresses) {
1475 InetAddress inetAddr = getInetAddress(allowedAddress.getIpAddress());
1476 if (inetAddr != null && !inetAddr.isMulticastAddress()) {
1477 filteredAAPs.add(allowedAddress);
1480 return filteredAAPs;
1483 public static String getRecoverServiceRegistryKey() {
1484 return NetvirtAcl.class.toString();
1487 private static InetAddress getInetAddress(IpPrefixOrAddress ipPrefixOrAddress) {
1488 InetAddress inetAddress = null;
1491 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
1492 if (ipPrefix != null) {
1493 addr = ipPrefix.stringValue().split("/")[0];
1495 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
1496 if (ipAddress == null) {
1497 LOG.error("Invalid address : {}", ipPrefixOrAddress);
1500 addr = ipAddress.stringValue();
1504 inetAddress = InetAddress.getByName(addr);
1505 } catch (UnknownHostException e) {
1506 LOG.error("Invalid address : {}", addr, e);
1512 public static Boolean isIpv6Subnet(List<SubnetInfo> subnetInfoList) {
1513 if (subnetInfoList != null && !subnetInfoList.isEmpty()) {
1514 for (SubnetInfo subnetInfo : subnetInfoList) {
1515 if (subnetInfo != null && IpVersionV6.class.equals(subnetInfo.getIpVersion())) {
1524 * Gets the subnet difference by performing (subnetInfo1 - subnetInfo2).
1526 * @param subnetInfo1 the subnet info 1
1527 * @param subnetInfo2 the subnet info 2
1528 * @return the subnet diff
1530 public static List<SubnetInfo> getSubnetDiff(List<SubnetInfo> subnetInfo1, List<SubnetInfo> subnetInfo2) {
1531 if (subnetInfo1 == null) {
1532 return Collections.emptyList();
1534 List<SubnetInfo> newSubnetList = new ArrayList<>(subnetInfo1);
1535 if (subnetInfo2 == null) {
1536 return newSubnetList;
1538 newSubnetList.removeAll(subnetInfo2);
1539 return newSubnetList;