X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnservice%2Faclservice%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Faclservice%2Futils%2FAclServiceUtils.java;h=5b7c5a87f5d290cd688433f09ce448af03e570b6;hb=ab59b533b9003c1df4bd05f09133be94dc9e82a2;hp=d4b5a3c7de398bdd8d4e74195f9de6f149af472b;hpb=b1723a110fbaa329209694d551da6fea2ddffa6f;p=netvirt.git diff --git a/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclServiceUtils.java b/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclServiceUtils.java index d4b5a3c7de..5b7c5a87f5 100644 --- a/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclServiceUtils.java +++ b/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclServiceUtils.java @@ -9,14 +9,22 @@ package org.opendaylight.netvirt.aclservice.utils; import com.google.common.base.Optional; +import com.googlecode.ipv6.IPv6Address; +import com.googlecode.ipv6.IPv6NetworkMask; + import java.math.BigInteger; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; + +import javax.inject.Inject; +import javax.inject.Singleton; + import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; @@ -45,6 +53,12 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput; @@ -60,6 +74,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.ser import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr; @@ -77,12 +92,21 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Singleton @SuppressWarnings("deprecation") public final class AclServiceUtils { private static final Logger LOG = LoggerFactory.getLogger(AclServiceUtils.class); - private AclServiceUtils() { } + private final AclDataUtil aclDataUtil; + private final AclserviceConfig config; + + @Inject + public AclServiceUtils(AclDataUtil aclDataUtil, AclserviceConfig config) { + super(); + this.aclDataUtil = aclDataUtil; + this.config = config; + } /** * Retrieves the Interface from the datastore. @@ -113,6 +137,7 @@ public final class AclServiceUtils { * @param broker the data broker. * @param datastoreType the data store type. * @param path the wild card path. + * @param type of DataObject * @return the required object. */ public static Optional read( @@ -445,28 +470,33 @@ public final class AclServiceUtils { IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix(); MatchFieldType matchFieldType; if (ipPrefix != null) { - if (ipPrefix.getIpv4Prefix().getValue() != null) { + if (ipPrefix.getIpv4Prefix() != null) { flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4})); String[] ipaddressValues = ipPrefix.getIpv4Prefix().getValue().split("/"); - matchFieldType = (matchCriteria == MatchCriteria.MATCH_SOURCE) + matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE ? MatchFieldType.ipv4_source : MatchFieldType.ipv4_destination; flowMatches.add(new MatchInfo(matchFieldType, new String[] {ipaddressValues[0], ipaddressValues[1]})); } else { - matchFieldType = (matchCriteria == MatchCriteria.MATCH_SOURCE) + matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE ? MatchFieldType.ipv6_source : MatchFieldType.ipv6_destination; + String[] ipv6addressValues = ipPrefix.getIpv6Prefix().getValue().split("/"); + IPv6Address ipv6Address = IPv6Address.fromString(ipv6addressValues[0]); + IPv6Address maskedV6Address = ipv6Address.maskWithNetworkMask( + IPv6NetworkMask.fromPrefixLength(Integer.parseInt(ipv6addressValues[1]))); flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6})); - flowMatches.add(new MatchInfo(matchFieldType, new String[] {ipPrefix.getIpv6Prefix().getValue()})); + flowMatches.add(new MatchInfo(matchFieldType, + new String[] {maskedV6Address.toString() + "/" + ipv6addressValues[1]})); } } else { IpAddress ipAddress = ipPrefixOrAddress.getIpAddress(); if (ipAddress.getIpv4Address() != null) { - matchFieldType = (matchCriteria == MatchCriteria.MATCH_SOURCE) + matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE ? MatchFieldType.ipv4_source : MatchFieldType.ipv4_destination; flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4})); flowMatches.add(new MatchInfo(matchFieldType, new String[] {ipAddress.getIpv4Address().getValue(), "32"})); } else { - matchFieldType = (matchCriteria == MatchCriteria.MATCH_SOURCE) + matchFieldType = matchCriteria == MatchCriteria.MATCH_SOURCE ? MatchFieldType.ipv6_source : MatchFieldType.ipv6_destination; flowMatches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6})); flowMatches.add(new MatchInfo(matchFieldType, @@ -503,16 +533,17 @@ public final class AclServiceUtils { return remoteAclRuleList; } - public static Map> getFlowForRemoteAcl(Uuid remoteAclId, String ignoreInterfaceId, + public Map> getFlowForRemoteAcl(Uuid remoteAclId, String ignoreInterfaceId, Map> flowMatchesMap, boolean isSourceIpMacMatch) { - List interfaceList = AclDataUtil.getInterfaceList(remoteAclId); + List interfaceList = aclDataUtil.getInterfaceList(remoteAclId); if (flowMatchesMap == null || interfaceList == null || interfaceList.isEmpty()) { return null; } Map> updatedFlowMatchesMap = new HashMap<>(); MatchInfoBase ipv4Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4}); + MatchInfoBase ipv6Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6}); for (String flowName : flowMatchesMap.keySet()) { List flows = flowMatchesMap.get(flowName); for (AclInterface port : interfaceList) { @@ -525,15 +556,15 @@ public final class AclServiceUtils { for (AllowedAddressPairs aap : allowedAddressPair) { List matchInfoBaseList; String flowId; - if (flows.contains(ipv4Match)) { + if (flows.contains(ipv4Match) && isIPv4Address(aap)) { matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap); flowId = flowName + "_ipv4_remoteACL_interface_aap_" + aap.getKey(); - } else { - // TODO: handle AAP matches for ipv6 - matchInfoBaseList = flows; + updatedFlowMatchesMap.put(flowId, matchInfoBaseList); + } else if (flows.contains(ipv6Match) && !isIPv4Address(aap)) { + matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap); flowId = flowName + "_ipv6_remoteACL_interface_aap_" + aap.getKey(); + updatedFlowMatchesMap.put(flowId, matchInfoBaseList); } - updatedFlowMatchesMap.put(flowId, matchInfoBaseList); } } @@ -542,6 +573,26 @@ public final class AclServiceUtils { return updatedFlowMatchesMap; } + public AclserviceConfig getConfig() { + return config; + } + + private static boolean isIPv4Address(AllowedAddressPairs aap) { + IpPrefixOrAddress ipPrefixOrAddress = aap.getIpAddress(); + IpPrefix ipPrefix = ipPrefixOrAddress.getIpPrefix(); + if (ipPrefix != null) { + if (ipPrefix.getIpv4Prefix() != null) { + return true; + } + } else { + IpAddress ipAddress = ipPrefixOrAddress.getIpAddress(); + if (ipAddress.getIpv4Address() != null) { + return true; + } + } + return false; + } + public static Map> getFlowForAllowedAddresses(List syncAllowedAddresses, Map> @@ -552,21 +603,22 @@ public final class AclServiceUtils { } Map> updatedFlowMatchesMap = new HashMap<>(); MatchInfoBase ipv4Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV4}); + MatchInfoBase ipv6Match = new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_IPV6}); for (String flowName : flowMatchesMap.keySet()) { List flows = flowMatchesMap.get(flowName); // iterate over allow address pair and update match type for (AllowedAddressPairs aap : syncAllowedAddresses) { List matchInfoBaseList; String flowId; - if (flows.contains(ipv4Match)) { + if (flows.contains(ipv4Match) && isIPv4Address(aap)) { matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap); flowId = flowName + "_ipv4_remoteACL_interface_aap_" + aap.getKey(); - } else { - // TODO: handle AAP matches for ipv6 - matchInfoBaseList = flows; + updatedFlowMatchesMap.put(flowId, matchInfoBaseList); + } else if (flows.contains(ipv6Match) && !isIPv4Address(aap)) { + matchInfoBaseList = updateAAPMatches(isSourceIpMacMatch, flows, aap); flowId = flowName + "_ipv6_remoteACL_interface_aap_" + aap.getKey(); + updatedFlowMatchesMap.put(flowId, matchInfoBaseList); } - updatedFlowMatchesMap.put(flowId, matchInfoBaseList); } } @@ -633,11 +685,11 @@ public final class AclServiceUtils { return mib; } - public static MatchInfoBase getMatchInfoByType(List flows, MatchFieldType type) { + public static MatchInfo getMatchInfoByType(List flows, MatchFieldType type) { for (MatchInfoBase mib : flows) { if (mib instanceof MatchInfo) { if (((MatchInfo)mib).getMatchField() == type) { - return mib; + return (MatchInfo) mib; } } } @@ -670,4 +722,51 @@ public final class AclServiceUtils { } return false; } + + public static boolean containsMatchFieldTypeAndValue(List flows, MatchFieldType type, + long[] values) { + MatchInfo mib = getMatchInfoByType(flows, type); + if (mib != null && Arrays.equals(mib.getMatchValues(), values)) { + return true; + } + + return false; + } + + public static boolean containsTcpMatchField(List flows) { + return containsMatchFieldTypeAndValue(flows, MatchFieldType.ip_proto, new long[] {IPProtocols.TCP.intValue()}); + } + + public static boolean containsUdpMatchField(List flows) { + return containsMatchFieldTypeAndValue(flows, MatchFieldType.ip_proto, new long[] {IPProtocols.UDP.intValue()}); + } + + public static Integer allocateId(IdManagerService idManager, String poolName, String idKey) { + AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); + try { + Future> result = idManager.allocateId(getIdInput); + RpcResult rpcResult = result.get(); + if (rpcResult.isSuccessful()) { + return rpcResult.getResult().getIdValue().intValue(); + } else { + LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors()); + } + } catch (InterruptedException | ExecutionException e) { + LOG.warn("Exception when getting Unique Id", e); + } + return AclConstants.PROTO_MATCH_PRIORITY; + } + + public static void releaseId(IdManagerService idManager, String poolName, String idKey) { + ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build(); + try { + Future> result = idManager.releaseId(idInput); + RpcResult rpcResult = result.get(); + if (!rpcResult.isSuccessful()) { + LOG.warn("RPC Call to release Id {} with Key {} returned with Errors {}", idKey, rpcResult.getErrors()); + } + } catch (InterruptedException | ExecutionException e) { + LOG.warn("Exception when releasing Id for key {}", idKey, e); + } + } }