2 * Copyright (c) 2016 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 com.google.common.base.Optional;
12 import com.googlecode.ipv6.IPv6Address;
13 import com.googlecode.ipv6.IPv6NetworkMask;
15 import java.math.BigInteger;
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.List;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.Future;
25 import javax.inject.Inject;
26 import javax.inject.Singleton;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
30 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
31 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
32 import org.opendaylight.genius.mdsalutil.MDSALUtil;
33 import org.opendaylight.genius.mdsalutil.MatchFieldType;
34 import org.opendaylight.genius.mdsalutil.MatchInfo;
35 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
36 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
37 import org.opendaylight.genius.mdsalutil.NwConstants;
38 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
39 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
40 import org.opendaylight.genius.mdsalutil.packet.IPProtocols;
41 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.MatchCriteria;
42 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AccessLists;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
88 import org.opendaylight.yangtools.yang.binding.DataObject;
89 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
90 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
91 import org.opendaylight.yangtools.yang.common.RpcResult;
92 import org.slf4j.Logger;
93 import org.slf4j.LoggerFactory;
96 @SuppressWarnings("deprecation")
97 public final class AclServiceUtils {
99 private static final Logger LOG = LoggerFactory.getLogger(AclServiceUtils.class);
101 private final AclDataUtil aclDataUtil;
102 private final AclserviceConfig config;
105 public AclServiceUtils(AclDataUtil aclDataUtil, AclserviceConfig config) {
107 this.aclDataUtil = aclDataUtil;
108 this.config = config;
112 * Retrieves the Interface from the datastore.
113 * @param broker the data broker
114 * @param interfaceName the interface name
115 * @return the interface.
117 public static Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
118 .Interface> getInterface(DataBroker broker, String interfaceName) {
119 return read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
123 * Builds the interface identifier.
124 * @param interfaceName the interface name.
125 * @return the interface identifier.
127 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
128 .interfaces.Interface> getInterfaceIdentifier(String interfaceName) {
129 return InstanceIdentifier.builder(Interfaces.class)
131 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
132 .Interface.class, new InterfaceKey(interfaceName)).build();
136 * Retrieves the object from the datastore.
137 * @param broker the data broker.
138 * @param datastoreType the data store type.
139 * @param path the wild card path.
140 * @param <T> type of DataObject
141 * @return the required object.
143 public static <T extends DataObject> Optional<T> read(
144 DataBroker broker, LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
146 Optional<T> result = Optional.absent();
147 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
149 result = tx.read(datastoreType, path).checkedGet();
150 } catch (ReadFailedException e) {
151 LOG.warn("Failed to read InstanceIdentifier {} from {}", path, datastoreType, e);
159 * Retrieves the acl matching the key from the data store.
161 * @param broker the data broker
162 * @param aclKey the acl key
165 public static Acl getAcl(DataBroker broker, String aclKey) {
166 return read(broker, LogicalDatastoreType.CONFIGURATION, getAclInstanceIdentifier(aclKey)).orNull();
169 /** Creates the Acl instance identifier.
171 * @param aclKey the acl key
172 * @return the instance identifier
174 public static InstanceIdentifier<Acl> getAclInstanceIdentifier(String aclKey) {
175 return InstanceIdentifier
176 .builder(AccessLists.class)
178 new AclKey(aclKey,Ipv4Acl.class))
183 * Get the data path number for the interface.
184 * @param interfaceManagerRpcService interfaceManagerRpcService instance.
185 * @param ifName the interface name.
188 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
189 BigInteger nodeId = BigInteger.ZERO;
191 GetDpidFromInterfaceInput dpIdInput =
192 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
193 Future<RpcResult<GetDpidFromInterfaceOutput>> dpIdOutput =
194 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
195 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
196 if (dpIdResult.isSuccessful()) {
197 nodeId = dpIdResult.getResult().getDpid();
199 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
201 } catch (NullPointerException | InterruptedException | ExecutionException e) {
202 LOG.error("Exception when getting dpn for interface {}", ifName, e);
208 * Retrieves the interface state.
209 * @param dataBroker the data broker.
210 * @param interfaceName the interface name.
211 * @return the interface state.
213 public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state
214 .Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
215 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
216 .interfaces.state.Interface> ifStateId = buildStateInterfaceId(interfaceName);
217 return MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, dataBroker).orNull();
221 * Build the interface state.
222 * @param interfaceName the interface name.
223 * @return the interface state.
225 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
226 .interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
227 InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
228 .interfaces.state.Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
229 .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
230 .state.Interface.class, new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
231 .rev140508.interfaces.state.InterfaceKey(interfaceName));
232 return idBuilder.build();
236 * Checks whether port security is enabled for the port.
237 * @param port the port.
238 * @return the port security is enabled/not.
240 public static boolean isPortSecurityEnabled(AclInterface port) {
241 return port.isPortSecurityEnabled();
245 * Checks whether port security is enabled for the port.
246 * @param port the port.
247 * @return the list of security groups.
249 public static List<Uuid> getInterfaceAcls(Interface port) {
251 LOG.error("Port is Null");
254 InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
255 if (aclInPort == null) {
256 LOG.error("getSecurityGroupInPortList: no security group associated}",
260 return aclInPort.getSecurityGroups();
264 * Retrieves the security rule attribute augmentation from the access list.
265 * @param ace the access list entry
266 * @return the security rule attributes
268 public static SecurityRuleAttr getAccesssListAttributes(Ace ace) {
270 LOG.error("Ace is Null");
273 SecurityRuleAttr aceAttributes = ace.getAugmentation(SecurityRuleAttr.class);
274 if (aceAttributes == null) {
275 LOG.error("Ace is null");
278 return aceAttributes;
282 * Returns the DHCP match.
284 * @param srcPort the source port.
285 * @param dstPort the destination port.
286 * @param lportTag the lport tag
287 * @return list of matches.
289 public static List<MatchInfoBase> buildDhcpMatches(int srcPort, int dstPort, int lportTag) {
290 List<MatchInfoBase> matches = new ArrayList<>(6);
291 matches.add(new MatchInfo(MatchFieldType.eth_type,
292 new long[] { NwConstants.ETHTYPE_IPV4 }));
293 matches.add(new MatchInfo(MatchFieldType.ip_proto,
294 new long[] { IPProtocols.UDP.intValue() }));
295 matches.add(new MatchInfo(MatchFieldType.udp_dst,
296 new long[] { dstPort }));
297 matches.add(new MatchInfo(MatchFieldType.udp_src,
298 new long[] { srcPort}));
299 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
304 * Returns the DHCPv6 match.
306 * @param srcPort the source port.
307 * @param dstPort the destination port.
308 * @param lportTag the lport tag
309 * @return list of matches.
311 public static List<MatchInfoBase> buildDhcpV6Matches(int srcPort, int dstPort, int lportTag) {
312 List<MatchInfoBase> matches = new ArrayList<>(6);
313 matches.add(new MatchInfo(MatchFieldType.eth_type,
314 new long[] { NwConstants.ETHTYPE_IPV6 }));
315 matches.add(new MatchInfo(MatchFieldType.ip_proto,
316 new long[] { IPProtocols.UDP.intValue() }));
317 matches.add(new MatchInfo(MatchFieldType.udp_dst,
318 new long[] { dstPort }));
319 matches.add(new MatchInfo(MatchFieldType.udp_src,
320 new long[] { srcPort}));
321 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
326 * Returns the ICMPv6 match.
328 * @param icmpType the icmpv6-type.
329 * @param icmpCode the icmpv6-code.
330 * @param lportTag the lport tag
331 * @return list of matches.
333 public static List<MatchInfoBase> buildIcmpV6Matches(int icmpType, int icmpCode, int lportTag) {
334 List<MatchInfoBase> matches = new ArrayList<>(6);
335 matches.add(new MatchInfo(MatchFieldType.eth_type,
336 new long[] { NwConstants.ETHTYPE_IPV6 }));
337 matches.add(new MatchInfo(MatchFieldType.ip_proto,
338 new long[] { IPProtocols.IPV6ICMP.intValue() }));
340 matches.add(new MatchInfo(MatchFieldType.icmp_v6,
341 new long[] { icmpType, icmpCode}));
343 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
348 * Builds the service id.
350 * @param interfaceName the interface name
351 * @param serviceIndex the service index
352 * @param serviceMode the service mode
353 * @return the instance identifier
355 public static InstanceIdentifier<BoundServices> buildServiceId(String interfaceName, short serviceIndex,
356 Class<? extends ServiceModeBase> serviceMode) {
357 return InstanceIdentifier.builder(ServiceBindings.class)
358 .child(ServicesInfo.class, new ServicesInfoKey(interfaceName, serviceMode))
359 .child(BoundServices.class, new BoundServicesKey(serviceIndex)).build();
363 * Gets the bound services.
365 * @param serviceName the service name
366 * @param servicePriority the service priority
367 * @param flowPriority the flow priority
368 * @param cookie the cookie
369 * @param instructions the instructions
370 * @return the bound services
372 public static BoundServices getBoundServices(String serviceName, short servicePriority, int flowPriority,
373 BigInteger cookie, List<Instruction> instructions) {
374 StypeOpenflowBuilder augBuilder = new StypeOpenflowBuilder().setFlowCookie(cookie).setFlowPriority(flowPriority)
375 .setInstruction(instructions);
376 return new BoundServicesBuilder().setKey(new BoundServicesKey(servicePriority)).setServiceName(serviceName)
377 .setServicePriority(servicePriority).setServiceType(ServiceTypeFlowBased.class)
378 .addAugmentation(StypeOpenflow.class, augBuilder.build()).build();
381 public static List<Uuid> getUpdatedAclList(List<Uuid> updatedAclList, List<Uuid> currentAclList) {
382 if (updatedAclList == null) {
385 List<Uuid> newAclList = new ArrayList<>(updatedAclList);
386 if (currentAclList == null) {
389 List<Uuid> origAclList = new ArrayList<>(currentAclList);
390 for (Iterator<Uuid> iterator = newAclList.iterator(); iterator.hasNext();) {
391 Uuid updatedAclUuid = iterator.next();
392 for (Uuid currentAclUuid :origAclList) {
393 if (updatedAclUuid.getValue().equals(currentAclUuid.getValue())) {
401 public static List<AllowedAddressPairs> getUpdatedAllowedAddressPairs(
402 List<AllowedAddressPairs> updatedAllowedAddressPairs,
403 List<AllowedAddressPairs> currentAllowedAddressPairs) {
404 if (updatedAllowedAddressPairs == null) {
407 List<AllowedAddressPairs> newAllowedAddressPairs = new ArrayList<>(updatedAllowedAddressPairs);
408 if (currentAllowedAddressPairs == null) {
409 return newAllowedAddressPairs;
411 List<AllowedAddressPairs> origAllowedAddressPairs = new ArrayList<>(currentAllowedAddressPairs);
412 for (Iterator<AllowedAddressPairs> iterator = newAllowedAddressPairs.iterator(); iterator.hasNext();) {
413 AllowedAddressPairs updatedAllowedAddressPair = iterator.next();
414 for (AllowedAddressPairs currentAllowedAddressPair : origAllowedAddressPairs) {
415 if (updatedAllowedAddressPair.getKey().equals(currentAllowedAddressPair.getKey())) {
421 return newAllowedAddressPairs;
424 public static List<AllowedAddressPairs> getPortAllowedAddresses(Interface port) {
426 LOG.error("Port is Null");
429 InterfaceAcl aclInPort = port.getAugmentation(InterfaceAcl.class);
430 if (aclInPort == null) {
431 LOG.error("getSecurityGroupInPortList: no security group associated to Interface port: {}", port.getName());
434 return aclInPort.getAllowedAddressPairs();
437 public static BigInteger getDpIdFromIterfaceState(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
438 .interfaces.rev140508.interfaces.state.Interface interfaceState) {
439 BigInteger dpId = null;
440 List<String> ofportIds = interfaceState.getLowerLayerIf();
441 if (ofportIds != null && !ofportIds.isEmpty()) {
442 NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
443 dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
449 * Builds the ip matches.
451 * @param ipPrefixOrAddress the ip prefix or address
452 * @param matchCriteria the source_ip or destination_ip used for the match
455 public static List<MatchInfoBase> buildIpMatches(IpPrefixOrAddress ipPrefixOrAddress,
456 MatchCriteria matchCriteria) {
457 List<MatchInfoBase> flowMatches = new ArrayList<>();
458 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
459 MatchFieldType matchFieldType;
460 if (ipPrefix != null) {
461 if (ipPrefix.getIpv4Prefix() != null) {
462 flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4}));
463 String[] ipaddressValues = ipPrefix.getIpv4Prefix().getValue().split("/");
464 matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE
465 ? MatchFieldType.ipv4_source : MatchFieldType.ipv4_destination;
466 flowMatches.add(new MatchInfo(matchFieldType, new String[] {ipaddressValues[0], ipaddressValues[1]}));
468 matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE
469 ? MatchFieldType.ipv6_source : MatchFieldType.ipv6_destination;
470 String[] ipv6addressValues = ipPrefix.getIpv6Prefix().getValue().split("/");
471 IPv6Address ipv6Address = IPv6Address.fromString(ipv6addressValues[0]);
472 IPv6Address maskedV6Address = ipv6Address.maskWithNetworkMask(
473 IPv6NetworkMask.fromPrefixLength(Integer.parseInt(ipv6addressValues[1])));
474 flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6}));
475 flowMatches.add(new MatchInfo(matchFieldType,
476 new String[] {maskedV6Address.toString() + "/" + ipv6addressValues[1]}));
479 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
480 if (ipAddress.getIpv4Address() != null) {
481 matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE
482 ? MatchFieldType.ipv4_source : MatchFieldType.ipv4_destination;
483 flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4}));
484 flowMatches.add(new MatchInfo(matchFieldType,
485 new String[] {ipAddress.getIpv4Address().getValue(), "32"}));
487 matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE
488 ? MatchFieldType.ipv6_source : MatchFieldType.ipv6_destination;
489 flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6}));
490 flowMatches.add(new MatchInfo(matchFieldType,
491 new String[] {ipAddress.getIpv6Address().getValue() + "/128" }));
498 * Gets the lport tag match.
500 * @param lportTag the lport tag
501 * @return the lport tag match
503 public static MatchInfo buildLPortTagMatch(int lportTag) {
504 return new MatchInfo(MatchFieldType.metadata,
505 new BigInteger[] {MetaDataUtil.getLportTagMetaData(lportTag), MetaDataUtil.METADATA_MASK_LPORT_TAG});
508 public static List<Ace> getAceWithRemoteAclId(DataBroker dataBroker, AclInterface port, Uuid remoteAcl) {
509 List<Ace> remoteAclRuleList = new ArrayList<>();
510 List<Uuid> aclList = port.getSecurityGroups();
511 for (Uuid aclId : aclList) {
512 Acl acl = getAcl(dataBroker, aclId.getValue());
513 List<Ace> aceList = acl.getAccessListEntries().getAce();
514 for (Ace ace : aceList) {
515 Uuid tempRemoteAcl = getAccesssListAttributes(ace).getRemoteGroupId();
516 if (tempRemoteAcl != null && tempRemoteAcl.equals(remoteAcl)) {
517 remoteAclRuleList.add(ace);
521 return remoteAclRuleList;
524 public Map<String, List<MatchInfoBase>> getFlowForRemoteAcl(Uuid remoteAclId, String ignoreInterfaceId,
525 Map<String, List<MatchInfoBase>>
526 flowMatchesMap, boolean
527 isSourceIpMacMatch) {
528 List<AclInterface> interfaceList = aclDataUtil.getInterfaceList(remoteAclId);
529 if (flowMatchesMap == null || interfaceList == null || interfaceList.isEmpty()) {
532 Map<String, List<MatchInfoBase>> updatedFlowMatchesMap = new HashMap<>();
533 MatchInfoBase ipv4Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4});
534 MatchInfoBase ipv6Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6});
535 for (String flowName : flowMatchesMap.keySet()) {
536 List<MatchInfoBase> flows = flowMatchesMap.get(flowName);
537 for (AclInterface port : interfaceList) {
538 if (port.getInterfaceId().equals(ignoreInterfaceId)) {
541 //get allow address pair
542 List<AllowedAddressPairs> allowedAddressPair = port.getAllowedAddressPairs();
543 // iterate over allow address pair and update match type
544 for (AllowedAddressPairs aap : allowedAddressPair) {
545 List<MatchInfoBase> matchInfoBaseList;
547 if (flows.contains(ipv4Match) && isIPv4Address(aap)) {
548 matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
549 flowId = flowName + "_ipv4_remoteACL_interface_aap_" + aap.getKey();
550 updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
551 } else if (flows.contains(ipv6Match) && !isIPv4Address(aap)) {
552 matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
553 flowId = flowName + "_ipv6_remoteACL_interface_aap_" + aap.getKey();
554 updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
561 return updatedFlowMatchesMap;
564 public AclserviceConfig getConfig() {
568 private static boolean isIPv4Address(AllowedAddressPairs aap) {
569 IpPrefixOrAddress ipPrefixOrAddress = aap.getIpAddress();
570 IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix();
571 if (ipPrefix != null) {
572 if (ipPrefix.getIpv4Prefix() != null) {
576 IpAddress ipAddress = ipPrefixOrAddress.getIpAddress();
577 if (ipAddress.getIpv4Address() != null) {
584 public static Map<String, List<MatchInfoBase>> getFlowForAllowedAddresses(List<AllowedAddressPairs>
585 syncAllowedAddresses,
586 Map<String, List<MatchInfoBase>>
587 flowMatchesMap, boolean
588 isSourceIpMacMatch) {
589 if (flowMatchesMap == null) {
592 Map<String, List<MatchInfoBase>> updatedFlowMatchesMap = new HashMap<>();
593 MatchInfoBase ipv4Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4});
594 MatchInfoBase ipv6Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6});
595 for (String flowName : flowMatchesMap.keySet()) {
596 List<MatchInfoBase> flows = flowMatchesMap.get(flowName);
597 // iterate over allow address pair and update match type
598 for (AllowedAddressPairs aap : syncAllowedAddresses) {
599 List<MatchInfoBase> matchInfoBaseList;
601 if (flows.contains(ipv4Match) && isIPv4Address(aap)) {
602 matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
603 flowId = flowName + "_ipv4_remoteACL_interface_aap_" + aap.getKey();
604 updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
605 } else if (flows.contains(ipv6Match) && !isIPv4Address(aap)) {
606 matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap);
607 flowId = flowName + "_ipv6_remoteACL_interface_aap_" + aap.getKey();
608 updatedFlowMatchesMap.put(flowId, matchInfoBaseList);
613 return updatedFlowMatchesMap;
616 public static Long getElanIdFromInterface(String elanInterfaceName,DataBroker broker) {
617 ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(elanInterfaceName, broker);
618 if (null != elanInterface) {
619 ElanInstance elanInfo = getElanInstanceByName(elanInterface.getElanInstanceName(), broker);
620 return elanInfo.getElanTag();
625 public static ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName,DataBroker broker) {
626 InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
627 return read(broker, LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull();
630 public static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
631 return InstanceIdentifier.builder(ElanInterfaces.class)
632 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
635 // elan-instances config container
636 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
637 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
638 return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
641 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
642 return InstanceIdentifier.builder(ElanInstances.class)
643 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
646 private static List<MatchInfoBase> updateAAPMatches(boolean isSourceIpMacMatch, List<MatchInfoBase> flows,
647 AllowedAddressPairs aap) {
648 List<MatchInfoBase> matchInfoBaseList;
649 if (isSourceIpMacMatch) {
650 matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchCriteria.MATCH_SOURCE);
652 matchInfoBaseList = AclServiceUtils.buildIpMatches(aap.getIpAddress(), MatchCriteria.MATCH_DESTINATION);
654 matchInfoBaseList.addAll(flows);
655 return matchInfoBaseList;
658 public static MatchInfoBase popMatchInfoByType(List<MatchInfoBase> flows, MatchFieldType type) {
659 MatchInfoBase mib = getMatchInfoByType(flows, type);
666 public static MatchInfo getMatchInfoByType(List<MatchInfoBase> flows, MatchFieldType type) {
667 for (MatchInfoBase mib : flows) {
668 if (mib instanceof MatchInfo) {
669 if (((MatchInfo)mib).getMatchField() == type) {
670 return (MatchInfo) mib;
677 public static MatchInfoBase getMatchInfoByType(List<MatchInfoBase> flows, NxMatchFieldType type) {
678 for (MatchInfoBase mib : flows) {
679 if (mib instanceof NxMatchInfo) {
680 if (((NxMatchInfo)mib).getMatchField() == type) {
688 public static boolean containsMatchFieldType(List<MatchInfoBase> flows, MatchFieldType type) {
689 MatchInfoBase mib = getMatchInfoByType(flows, type);
696 public static boolean containsMatchFieldType(List<MatchInfoBase> flows, NxMatchFieldType type) {
697 MatchInfoBase mib = getMatchInfoByType(flows, type);
704 public static boolean containsMatchFieldTypeAndValue(List<MatchInfoBase> flows, MatchFieldType type,
706 MatchInfo mib = getMatchInfoByType(flows, type);
707 if (mib != null && Arrays.equals(mib.getMatchValues(), values)) {
714 public static boolean containsTcpMatchField(List<MatchInfoBase> flows) {
715 return containsMatchFieldTypeAndValue(flows, MatchFieldType.ip_proto, new long[] {IPProtocols.TCP.intValue()});
718 public static boolean containsUdpMatchField(List<MatchInfoBase> flows) {
719 return containsMatchFieldTypeAndValue(flows, MatchFieldType.ip_proto, new long[] {IPProtocols.UDP.intValue()});
722 public static Integer allocateId(IdManagerService idManager, String poolName, String idKey) {
723 AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
725 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
726 RpcResult<AllocateIdOutput> rpcResult = result.get();
727 if (rpcResult.isSuccessful()) {
728 return rpcResult.getResult().getIdValue().intValue();
730 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
732 } catch (InterruptedException | ExecutionException e) {
733 LOG.warn("Exception when getting Unique Id", e);
735 return AclConstants.PROTO_MATCH_PRIORITY;
738 public static void releaseId(IdManagerService idManager, String poolName, String idKey) {
739 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
741 Future<RpcResult<Void>> result = idManager.releaseId(idInput);
742 RpcResult<Void> rpcResult = result.get();
743 if (!rpcResult.isSuccessful()) {
744 LOG.warn("RPC Call to release Id {} with Key {} returned with Errors {}", idKey, rpcResult.getErrors());
746 } catch (InterruptedException | ExecutionException e) {
747 LOG.warn("Exception when releasing Id for key {}", idKey, e);
752 * Indicates whether the interface has port security enabled.
753 * @param aclInterface the interface.
754 * @return true if port is security enabled.
756 public static boolean isOfInterest(AclInterface aclInterface) {
757 return aclInterface != null && aclInterface.getPortSecurityEnabled() != null
758 && aclInterface.isPortSecurityEnabled();