From: Tomas Cechvala Date: Thu, 26 Mar 2015 23:03:29 +0000 (-0700) Subject: Classifiers - implementation changes. X-Git-Tag: release/lithium~128^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=758bfdb0ec2ce78b460bc07ff75a57471c73ad80;p=groupbasedpolicy.git Classifiers - implementation changes. This commit solves bug 2883. Change-Id: I1b5b886734833bd30129c71be78eb3a5af4387a8 Signed-off-by: Tomas Cechvala --- diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java index 7a7937bfc..2ecfd5ebc 100644 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/PolicyEnforcer.java @@ -24,8 +24,10 @@ import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassificationResult; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Classifier; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ParamDerivator; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures; import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup; import org.opendaylight.groupbasedpolicy.resolver.EgKey; @@ -89,7 +91,7 @@ public class PolicyEnforcer extends FlowTable { @Override public void sync(ReadWriteTransaction t, InstanceIdentifier tiid, - Map flowMap, NodeId nodeId, + Map flowMap, NodeId nodeId, PolicyInfo policyInfo, Dirty dirty) throws Exception { dropFlow(t, tiid, flowMap, Integer.valueOf(1), null); @@ -100,12 +102,12 @@ public class PolicyEnforcer extends FlowTable { for (EgKey sepg : ctx.getEndpointManager().getGroupsForNode(nodeId)) { // Allow traffic within the same endpoint group if the policy // specifies - IndexedTenant tenant = + IndexedTenant tenant = ctx.getPolicyResolver().getTenant(sepg.getTenantId()); - EndpointGroup group = + EndpointGroup group = tenant.getEndpointGroup(sepg.getEgId()); IntraGroupPolicy igp = group.getIntraGroupPolicy(); - int sepgId = + int sepgId = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(), sepg.getEgId()); if (igp == null || igp.equals(IntraGroupPolicy.Allow)) { @@ -115,46 +117,45 @@ public class PolicyEnforcer extends FlowTable { for (Endpoint src : ctx.getEndpointManager().getEPsForNode(nodeId, sepg)) { if (src.getTenant() == null || src.getEndpointGroup() == null) continue; - - List conds = + + List conds = ctx.getEndpointManager().getCondsForEndpoint(src); ConditionGroup scg = policyInfo.getEgCondGroup(sepg, conds); int scgId = ctx.getPolicyManager().getCondGroupOrdinal(scg); - + Set peers = policyInfo.getPeers(sepg); for (EgKey depg : peers) { - int depgId = + int depgId = ctx.getPolicyManager().getContextOrdinal(depg.getTenantId(), depg.getEgId()); - + for (Endpoint dst : ctx.getEndpointManager().getEndpointsForGroup(depg)) { - + conds = ctx.getEndpointManager().getCondsForEndpoint(dst); - ConditionGroup dcg = + ConditionGroup dcg = policyInfo.getEgCondGroup(new EgKey(dst.getTenant(), dst.getEndpointGroup()), conds); int dcgId = ctx.getPolicyManager().getCondGroupOrdinal(dcg); - + CgPair p = new CgPair(depgId, sepgId, dcgId, scgId); if (visitedPairs.contains(p)) continue; visitedPairs.add(p); - syncPolicy(t, tiid, flowMap, nodeId, policyInfo, + syncPolicy(t, tiid, flowMap, nodeId, policyInfo, p, depg, sepg, dcg, scg); - + p = new CgPair(sepgId, depgId, scgId, dcgId); if (visitedPairs.contains(p)) continue; visitedPairs.add(p); - syncPolicy(t, tiid, flowMap, nodeId, policyInfo, + syncPolicy(t, tiid, flowMap, nodeId, policyInfo, p, sepg, depg, scg, dcg); - } } } } } - - private void allowSameEpg(ReadWriteTransaction t, + + private void allowSameEpg(ReadWriteTransaction t, InstanceIdentifier
tiid, Map flowMap, NodeId nodeId, int sepgId) { @@ -163,7 +164,7 @@ public class PolicyEnforcer extends FlowTable { .append(sepgId).toString()); if (visit(flowMap, flowId.getValue())) { MatchBuilder mb = new MatchBuilder(); - addNxRegMatch(mb, + addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class,Long.valueOf(sepgId)), RegMatch.of(NxmNxReg2.class,Long.valueOf(sepgId))); FlowBuilder flow = base() @@ -174,8 +175,8 @@ public class PolicyEnforcer extends FlowTable { writeFlow(t, tiid, flow.build()); } } - - private void allowFromTunnel(ReadWriteTransaction t, + + private void allowFromTunnel(ReadWriteTransaction t, InstanceIdentifier
tiid, Map flowMap, NodeId nodeId) { NodeConnectorId tunPort = @@ -186,7 +187,7 @@ public class PolicyEnforcer extends FlowTable { if (visit(flowMap, flowId.getValue())) { MatchBuilder mb = new MatchBuilder() .setInPort(tunPort); - addNxRegMatch(mb, + addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class,Long.valueOf(0xffffff))); FlowBuilder flow = base() .setId(flowId) @@ -196,19 +197,19 @@ public class PolicyEnforcer extends FlowTable { writeFlow(t, tiid, flow.build()); } } - - private void syncPolicy(ReadWriteTransaction t, + + private void syncPolicy(ReadWriteTransaction t, InstanceIdentifier
tiid, Map flowMap, NodeId nodeId, - PolicyInfo policyInfo, + PolicyInfo policyInfo, CgPair p, EgKey sepg, EgKey depg, - ConditionGroup scg, ConditionGroup dcg) + ConditionGroup scg, ConditionGroup dcg) throws Exception { // XXX - TODO raise an exception for rules between the same // endpoint group that are asymmetric Policy policy = policyInfo.getPolicy(sepg, depg); List rgs = policy.getRules(scg, dcg); - + int priority = 65000; for (RuleGroup rg : rgs) { TenantId tenantId = rg.getContractTenant().getId(); @@ -218,7 +219,7 @@ public class PolicyEnforcer extends FlowTable { p, r, Direction.In, priority); syncDirection(t, tiid, flowMap, nodeId, tenant, p, r, Direction.Out, priority); - + priority -= 1; } } @@ -249,7 +250,7 @@ public class PolicyEnforcer extends FlowTable { } - private void syncDirection(ReadWriteTransaction t, + private void syncDirection(ReadWriteTransaction t, InstanceIdentifier
tiid, Map flowMap, NodeId nodeId, IndexedTenant contractTenant, @@ -308,15 +309,14 @@ public class PolicyEnforcer extends FlowTable { abl = act.updateAction(abl, new HashMap(), 0); } - for (ClassifierRef cr : r.getClassifierRef()) { - if (cr.getDirection() != null && - !cr.getDirection().equals(Direction.Bidirectional) && + if (cr.getDirection() != null && + !cr.getDirection().equals(Direction.Bidirectional) && !cr.getDirection().equals(d)) continue; - + StringBuilder idb = new StringBuilder(); - // XXX - TODO - implement connection tracking (requires openflow + // XXX - TODO - implement connection tracking (requires openflow // extension and data plane support - in 2.4. Will need to handle // case where we are working with mix of nodes. @@ -332,7 +332,7 @@ public class PolicyEnforcer extends FlowTable { .append(p.dcgId) .append("|") .append(priority); - addNxRegMatch(baseMatch, + addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class,Long.valueOf(p.sepg)), RegMatch.of(NxmNxReg1.class,Long.valueOf(p.scgId)), RegMatch.of(NxmNxReg2.class,Long.valueOf(p.depg)), @@ -346,19 +346,18 @@ public class PolicyEnforcer extends FlowTable { .append("|") .append(p.scgId) .append("|") - .append(priority); - addNxRegMatch(baseMatch, + .append(priority); + addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class,Long.valueOf(p.depg)), RegMatch.of(NxmNxReg1.class,Long.valueOf(p.dcgId)), RegMatch.of(NxmNxReg2.class,Long.valueOf(p.sepg)), RegMatch.of(NxmNxReg3.class,Long.valueOf(p.scgId))); } - ClassifierInstance ci = contractTenant.getClassifier(cr.getName()); if (ci == null) { // XXX TODO fail the match and raise an exception - LOG.warn("Classifier instance {} not found", + LOG.warn("Classifier instance {} not found", cr.getName().getValue()); return; } @@ -366,41 +365,42 @@ public class PolicyEnforcer extends FlowTable { .getClassifier(ci.getClassifierDefinitionId()); if (cfier == null) { // XXX TODO fail the match and raise an exception - LOG.warn("Classifier definition {} not found", + LOG.warn("Classifier definition {} not found", ci.getClassifierDefinitionId().getValue()); return; } - List matches = Collections.singletonList(baseMatch); - Map params = new HashMap<>(); + Map params = new HashMap<>(); for (ParameterValue v : ci.getParameterValue()) { - if (v.getName() == null) continue; if (v.getIntValue() != null) { - params.put(v.getName().getValue(), v.getIntValue()); + params.put(v.getName().getValue(), v); } else if (v.getStringValue() != null) { - params.put(v.getName().getValue(), v.getStringValue()); + params.put(v.getName().getValue(), v); } else if (v.getRangeValue() != null) { - params.put(v.getName().getValue(), v.getRangeValue()); + params.put(v.getName().getValue(), v); } } - - matches = cfier.updateMatch(matches, params); - String baseId = idb.toString(); - FlowBuilder flow = base() - .setPriority(Integer.valueOf(priority)); - for (MatchBuilder match : matches) { - Match m = match.build(); - FlowId flowId = new FlowId(baseId + "|" + m.toString()); - if (visit(flowMap, flowId.getValue())) { - flow.setMatch(m) - .setId(flowId) - .setPriority(Integer.valueOf(priority)) - .setInstructions(instructions(applyActionIns(abl))); - writeFlow(t, tiid, flow.build()); + List> derivedParams = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(params); + for (Map flowParams : derivedParams) { + List matches = Collections.singletonList(new MatchBuilder(baseMatch.build())); + ClassificationResult result = cfier.updateMatch(matches, flowParams); + if(!result.isSuccessfull()) { + //TODO consider different handling. + throw new IllegalArgumentException(result.getMessage()); + } + String baseId = idb.toString(); + FlowBuilder flow = base().setPriority(Integer.valueOf(priority)); + for (MatchBuilder match : result.getMatchBuilders()) { + Match m = match.build(); + FlowId flowId = new FlowId(baseId + "|" + m.toString()); + if (visit(flowMap, flowId.getValue())) { + flow.setMatch(m).setId(flowId).setPriority(Integer.valueOf(priority)) + .setInstructions(instructions(applyActionIns(abl))); + writeFlow(t, tiid, flow.build()); + } } } - } - + } } @Immutable @@ -409,7 +409,7 @@ public class PolicyEnforcer extends FlowTable { private final int depg; private final int scgId; private final int dcgId; - + public CgPair(int sepg, int depg, int scgId, int dcgId) { super(); this.sepg = sepg; diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassificationResult.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassificationResult.java new file mode 100644 index 000000000..5f38f90a6 --- /dev/null +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassificationResult.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + +import java.util.List; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; + +import com.google.common.base.Preconditions; + +public class ClassificationResult { + + private final String message; + private final boolean isSuccessful; + private final List matchBuilders; + + public ClassificationResult(String errorMessage) { + this.message = Preconditions.checkNotNull(errorMessage); + this.isSuccessful = false; + matchBuilders = null; + } + + public ClassificationResult(List matches) { + message = ""; + this.matchBuilders = Preconditions.checkNotNull(matches); + this.isSuccessful = true; + } + + public List getMatchBuilders() { + if (isSuccessful == false) { + throw new IllegalStateException("Classification was not successfull."); + } + return matchBuilders; + } + + public String getMessage() { + return message; + } + + public boolean isSuccessfull() { + return isSuccessful; + } +} \ No newline at end of file diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/Classifier.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/Classifier.java index a8d4d0d46..bf59d95fd 100644 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/Classifier.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/Classifier.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html @@ -8,39 +8,133 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; + +import com.google.common.base.Strings; /** * Represent a classifier definition, and provide tools for generating flow * rules based on the classifier - * @author readams */ public abstract class Classifier { + + protected final Classifier parent; + + public static final EtherTypeClassifier ETHER_TYPE_CL = new EtherTypeClassifier(null); + public static final IpProtoClassifier IP_PROTO_CL = new IpProtoClassifier(ETHER_TYPE_CL); + public static final L4Classifier L4_CL = new L4Classifier(IP_PROTO_CL); + + protected Classifier(Classifier parent) { + this.parent = parent; + } + /** - * Get the classifier definition for this classifier - * @return the {@link ClassifierDefinition} for this classifier + * Get the classifier definition id for this classifier + * + * @return the {@link ClassifierDefinitionId} for this classifier */ public abstract ClassifierDefinitionId getId(); /** * Get the classifier definition for this classifier + * * @return the {@link ClassifierDefinition} for this classifier */ public abstract ClassifierDefinition getClassDef(); - + + /** + * @return parent classifier + * @see {@link ClassifierDefinition} + */ + public final Classifier getParent() { + return parent; + } + + /** + * Template method for resolving {@code matches}. + * + * @param matches list of builders containing {@code matches} to update + * @param params parameters of classifier-instance inserted by user + * @return result, which indicates if all the matching fields were updated successfully and + * contain updated {@code matches} + * @see {@link ClassificationResult} + */ + public final ClassificationResult updateMatch(List matches, Map params) { + if (params == null) { + return new ClassificationResult("Classifier: {" + this.getClassDef().getName() + "} No parameters present."); + } + List matchBuilders = matches; + try { + checkPresenceOfRequiredParams(params); + matchBuilders = this.update(matchBuilders, params); + Classifier parent = this.getParent(); + List updatedClassifiers = new ArrayList<>(); + updatedClassifiers.add(this); + while (parent != null) { + boolean hasReqParams = true; + try { + parent.checkPresenceOfRequiredParams(params); + } catch (IllegalArgumentException e) { + hasReqParams = false; + } + if (hasReqParams == true) { + matchBuilders = parent.update(matchBuilders, params); + updatedClassifiers.add(parent); + } + parent = parent.getParent(); + } + for (Classifier updatedClassifier : updatedClassifiers) { + updatedClassifier.checkPrereqs(matchBuilders); + } + } catch (IllegalArgumentException e) { + if (!Strings.isNullOrEmpty(e.getMessage())) { + return new ClassificationResult(e.getMessage()); + } else + return new ClassificationResult("Error while processing data of " + this.getClassDef().getName() + + " classifier. Classification was not successful."); + } + return new ClassificationResult(matchBuilders); + } + +/** + * Checks presence of required {@code params} in order to decide if classifier can update {@code matches} properly + * in method {@link #update(List, Map) + * @param params inserted parameters, not null + * @return true, if required parameters are present + * @throws IllegalArgumentException when any of required {@code params} is not present + * @see {@link #updateMatch(List, Map)} + */ + protected abstract void checkPresenceOfRequiredParams(Map params); + + /** + * Resolves {@code matches} from inserted {@code params} and updates them. + *

+ * Updates fields in {@code matches} or it can creates new matches. If it creates new matches it + * has to always use match from {@code matches} as parameter in constructor + * {@code MatchBuilder(Match base)} + * + * @param matches - fields to update + * @param params - input parameters + * @return updated {@code matches}. It is allowed to return new object. + * @throws IllegalArgumentException when update fails because of bad input + * (e.g. overriding existing matches with different values is not permitted) + */ + protected abstract List update(List matches, Map params); + /** - * Construct a set of matches that will apply to the traffic. Augment - * the existing list of matches or add new matches. It's important - * that the order of the returned list be consistent however - * @param matches The existing matches - * @param params the parameters for the classifier instance - * @return the updated list of matches (may be a different length) + * Checks whether prerequisites (required {@code matches}) for the match that this classifier + * updates are present + * according to Openflow specifications. + * + * @param matches input list of matches to check + * @throws IllegalArgumentException when any of prerequisites is not present */ - public abstract List updateMatch(List matches, - Map params); + protected abstract void checkPrereqs(List matches); } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/EtherTypeClassifier.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/EtherTypeClassifier.java index e752ed60d..70ba21e7a 100644 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/EtherTypeClassifier.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/EtherTypeClassifier.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html @@ -21,7 +21,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetType; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; @@ -31,21 +33,23 @@ import com.google.common.collect.ImmutableList; * Match on the ether type of the traffic */ public class EtherTypeClassifier extends Classifier { - public static final ClassifierDefinitionId ID = - new ClassifierDefinitionId("6a48ab45-a462-429d-b18c-3a575b2c8bef"); - protected static final String TYPE = "type"; - protected static final ClassifierDefinition DEF = - new ClassifierDefinitionBuilder() - .setId(ID) - .setName(new ClassifierName("ether_type")) - .setDescription(new Description("Match on the ether type of the traffic")) - .setParameter(ImmutableList.of(new ParameterBuilder() - .setName(new ParameterName(TYPE)) + + public static final ClassifierDefinitionId ID = new ClassifierDefinitionId("6a48ab45-a462-429d-b18c-3a575b2c8bef"); + public static final String ETHER_TYPE = "ethertype"; + protected static final ClassifierDefinition DEF = new ClassifierDefinitionBuilder().setId(ID) + .setName(new ClassifierName("ether_type")) + .setDescription(new Description("Match on the ether type of the traffic")) + .setParameter( + ImmutableList.of(new ParameterBuilder().setName(new ParameterName(ETHER_TYPE)) .setDescription(new Description("The ethertype to match against")) .setIsRequired(IsRequired.Required) .setType(Type.Int) .build())) - .build(); + .build(); + + protected EtherTypeClassifier(Classifier parent) { + super(parent); + } @Override public ClassifierDefinitionId getId() { @@ -58,23 +62,46 @@ public class EtherTypeClassifier extends Classifier { } @Override - public List updateMatch(List matches, - Map params) { - Object param = params.get(TYPE); - // XXX TODO generate exception and fail the match - if (param == null || !(param instanceof Long)) return matches; - Long type = (Long)param; + protected void checkPresenceOfRequiredParams(Map params) { + if (params.get(ETHER_TYPE) == null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+ Parameter ethertype not present."); + } + if (params.get(ETHER_TYPE).getIntValue() == null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+ Value of ethertype parameter is not present."); + } + } + + @Override + protected List update(List matches, Map params) { + Long type = params.get(ETHER_TYPE).getIntValue(); for (MatchBuilder match : matches) { EthernetMatchBuilder em; - if (match.getEthernetMatch() != null) - em = new EthernetMatchBuilder(match.getEthernetMatch()); - else + if (match.getEthernetMatch() != null) { + equalOrNotSetValidation(match.getEthernetMatch().getEthernetType(), type); + continue; + } else { em = new EthernetMatchBuilder(); - em.setEthernetType(new EthernetTypeBuilder() - .setType(new EtherType(type)).build()); + } + em.setEthernetType(new EthernetTypeBuilder().setType(new EtherType(type)).build()); match.setEthernetMatch(em.build()); } return matches; } + private void equalOrNotSetValidation(EthernetType ethTypeInMatch, long paramValue) { + if (ethTypeInMatch != null) { + if (paramValue != ethTypeInMatch.getType().getValue().longValue()) { + throw new IllegalArgumentException("Classification conflict at " + this.getClassDef().getName() + + ": Trying to override ether-type value: " + ethTypeInMatch.getType().getValue() + + " by value " + paramValue); + } + } + } + + @Override + protected void checkPrereqs(List matches) { + // So far EthType has no prereqs. + } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/IpProtoClassifier.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/IpProtoClassifier.java index e02f8d0c9..d884cec61 100644 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/IpProtoClassifier.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/IpProtoClassifier.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html @@ -8,8 +8,6 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -24,36 +22,36 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; /** * Match on the IP protocol of IP traffic */ -public class IpProtoClassifier extends EtherTypeClassifier { - public static final ClassifierDefinitionId ID = - new ClassifierDefinitionId("79c6fdb2-1e1a-4832-af57-c65baf5c2335"); - protected static final String PROTO = "proto"; - protected static final ClassifierDefinition DEF = - new ClassifierDefinitionBuilder() - .setId(ID) - .setParent(EtherTypeClassifier.ID) - .setName(new ClassifierName("ip_proto")) - .setDescription(new Description("Match on the IP protocol of IP traffic")) - .setParameter(ImmutableList.of(new ParameterBuilder() - .setName(new ParameterName(PROTO)) +public class IpProtoClassifier extends Classifier { + + public static final Long TCP = Long.valueOf(6); + public static final Long UDP = Long.valueOf(17); + public static final Long SCTP = Long.valueOf(132); + public static final String PROTO = "proto"; + public static final ClassifierDefinitionId ID = new ClassifierDefinitionId("79c6fdb2-1e1a-4832-af57-c65baf5c2335"); + protected static final ClassifierDefinition DEF = new ClassifierDefinitionBuilder().setId(ID) + .setParent(EtherTypeClassifier.ID) + .setName(new ClassifierName("ip_proto")) + .setDescription(new Description("Match on the IP protocol of IP traffic")) + .setParameter( + ImmutableList.of(new ParameterBuilder().setName(new ParameterName(PROTO)) .setDescription(new Description("The IP protocol to match against")) .setIsRequired(IsRequired.Required) .setType(Type.Int) .build())) - .build(); + .build(); - private static final Map ipv4 = - ImmutableMap.of(TYPE, FlowUtils.IPv4); - private static final Map ipv6 = - ImmutableMap.of(TYPE, FlowUtils.IPv6); + protected IpProtoClassifier(Classifier parent) { + super(parent); + } @Override public ClassifierDefinitionId getId() { @@ -66,36 +64,73 @@ public class IpProtoClassifier extends EtherTypeClassifier { } @Override - public List updateMatch(List matches, - Map params) { - Object param = params.get(PROTO); - // XXX TODO generate exception and fail the match - if (param == null || !(param instanceof Long)) return matches; - Long proto = (Long)param; - - ArrayList r = new ArrayList<>(); - for (MatchBuilder b : matches) { - r.addAll(updateMatch(new MatchBuilder(b.build()), proto, ipv4)); - r.addAll(updateMatch(new MatchBuilder(b.build()), proto, ipv6)); + protected void checkPresenceOfRequiredParams(Map params) { + if (params.get(PROTO) == null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+ Parameter proto not present."); + } + if (params.get(PROTO).getIntValue() == null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+ Value of proto parameter is not present."); } - return r; } - private List updateMatch(MatchBuilder match, - Long proto, - Map parentParams) { - List r = - super.updateMatch(Collections.singletonList(match), - parentParams); - for (MatchBuilder mb : r) { + @Override + protected List update(List matches, Map params) { + Long proto = params.get(PROTO).getIntValue(); + for (MatchBuilder match : matches) { IpMatchBuilder imb; - if (mb.getIpMatch() != null) - imb = new IpMatchBuilder(mb.getIpMatch()); - else + if (match.getIpMatch() != null) { + equalOrNotSetValidation(match.getIpMatch().getIpProtocol(), proto); + continue; + } else { imb = new IpMatchBuilder(); + } imb.setIpProtocol(proto.shortValue()); - mb.setIpMatch(imb.build()); + match.setIpMatch(imb.build()); + } + return matches; + } + + private void equalOrNotSetValidation(Short protoInMatch, long paramValue) { + if (protoInMatch != null) { + if (paramValue != protoInMatch.longValue()) { + throw new IllegalArgumentException("Classification conflict at " + this.getClassDef().getName() + + ": Trying to override proto value: " + protoInMatch.shortValue() + " by value " + paramValue); + } + } + } + + @Override + protected void checkPrereqs(List matches) { + for (MatchBuilder match : matches) { + Long readEthType = null; + try { + readEthType = match.getEthernetMatch().getEthernetType().getType().getValue(); + } catch (NullPointerException e) { + throw new IllegalArgumentException("Ether-type match is missing."); + } + if (!FlowUtils.IPv4.equals(readEthType) && !FlowUtils.IPv6.equals(readEthType)) { + throw new IllegalArgumentException("Ether-type value should be " + FlowUtils.IPv4 + " or " + + FlowUtils.IPv6 + "."); + } + } + } + + /** + * May return null. + */ + public static Long getIpProtoValue(Map params) { + if (params == null) { + return null; + } + if (params.get(PROTO) == null) { + return null; + } + Long proto = params.get(PROTO).getIntValue(); + if (proto != null) { + return proto; } - return r; + return null; } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/L4Classifier.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/L4Classifier.java index 4f32e54db..ce15981b6 100755 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/L4Classifier.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/L4Classifier.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html @@ -9,6 +9,7 @@ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -16,79 +17,66 @@ import java.util.Map; import java.util.Set; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.IsRequired; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.ParameterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValue; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; /** * Match against TCP or UDP, and source and/or destination ports */ -public class L4Classifier extends IpProtoClassifier { - private static final Logger LOG = LoggerFactory.getLogger(L4Classifier.class); - public static final ClassifierDefinitionId ID = - new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f"); - private static final String SPORT = "sourceport"; - private static final String SPORT_RANGE = "sourceport_range"; - private static final String DPORT = "destport"; - private static final String DPORT_RANGE = "destport_range"; - private static final ClassifierDefinition DEF = - new ClassifierDefinitionBuilder() - .setId(new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f")) - .setParent(IpProtoClassifier.ID) - .setName(new ClassifierName("l4")) - .setDescription(new Description("Match on the port number of UDP or TCP traffic")) - .setParameter(ImmutableList.of(new ParameterBuilder() - .setName(new ParameterName(SPORT)) - .setDescription(new Description("The source port number to match against")) - .setType(Type.Int) - .build(), - new ParameterBuilder() - .setName(new ParameterName(SPORT_RANGE)) - .setDescription(new Description("The source port range to match against")) - .setType(Type.Range) - .build(), - new ParameterBuilder() - .setName(new ParameterName(DPORT)) - .setDescription(new Description("The destination port number to match against")) - .setType(Type.Int) - .build(), - new ParameterBuilder() - .setName(new ParameterName(DPORT_RANGE)) - .setDescription(new Description("The destination port range to match against")) - .setType(Type.Range) - .build(), - new ParameterBuilder() - .setName(new ParameterName(TYPE)) - .setDescription(new Description("TCP or UDP")) - .setIsRequired(IsRequired.Required) - .setType(Type.String) - .build())) - .build(); - - private static final Map tcp = - ImmutableMap.of(PROTO, Long.valueOf(6)); - private static final Map udp = - ImmutableMap.of(PROTO, Long.valueOf(17)); - +public class L4Classifier extends Classifier { + + public static final String SPORT = "sourceport"; + public static final String SPORT_RANGE = "sourceport_range"; + public static final String DPORT = "destport"; + public static final String DPORT_RANGE = "destport_range"; + public static final ClassifierDefinitionId ID = new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f"); + private static final ClassifierDefinition DEF = new ClassifierDefinitionBuilder().setId( + new ClassifierDefinitionId("4250ab32-e8b8-445a-aebb-e1bd2cdd291f")) + .setParent(IpProtoClassifier.ID) + .setName(new ClassifierName("l4")) + .setDescription(new Description("Match on the port number of UDP or TCP traffic")) + .setParameter( + ImmutableList.of( + new ParameterBuilder().setName(new ParameterName(SPORT)) + .setDescription(new Description("The source port number to match against")) + .setType(Type.Int) + .build(), + new ParameterBuilder().setName(new ParameterName(SPORT_RANGE)) + .setDescription(new Description("The source port range to match against")) + .setType(Type.Range) + .build(), + new ParameterBuilder().setName(new ParameterName(DPORT)) + .setDescription(new Description("The destination port number to match against")) + .setType(Type.Int) + .build(), + new ParameterBuilder().setName(new ParameterName(DPORT_RANGE)) + .setDescription(new Description("The destination port range to match against")) + .setType(Type.Range) + .build())) + .build(); + + protected L4Classifier(Classifier parent) { + super(parent); + } + @Override public ClassifierDefinitionId getId() { return ID; @@ -100,108 +88,223 @@ public class L4Classifier extends IpProtoClassifier { } @Override - public List updateMatch(List matches, - Map params) { - Object param = params.get(TYPE); - // XXX TODO generate exception and fail the match - if (param == null || !(param instanceof String)) return matches; - String type = (String) param; - - if ("UDP".equals(type)) - matches = super.updateMatch(matches, udp); - else - matches = super.updateMatch(matches, tcp); + protected void checkPresenceOfRequiredParams(Map params) { + if (params.get(SPORT) != null && params.get(SPORT_RANGE) != null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+. Illegal source port parameters: 'int' and 'range' values are mutually exclusive."); + } + if (params.get(DPORT) != null && params.get(DPORT_RANGE) != null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+. Illegal destination port parameters: 'int' and 'range' values are mutually exclusive."); + } + if (params.get(SPORT) != null) { + if (params.get(SPORT).getIntValue() == null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+ Value of sourceport parameter is not present."); + } + } + if (params.get(SPORT_RANGE) != null) { + if (params.get(SPORT_RANGE) != null) { + validateRangeValue(params.get(SPORT_RANGE).getRangeValue()); + } + } + + if (params.get(DPORT) != null) { + if (params.get(DPORT).getIntValue() == null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+ Value of destport parameter is not present."); + } + } + if (params.get(DPORT_RANGE) != null) { + if (params.get(DPORT_RANGE) != null) { + validateRangeValue(params.get(DPORT_RANGE).getRangeValue()); + } + } + } + + private void validateRangeValue(RangeValue rangeValueParam) { + if (rangeValueParam == null) { + throw new IllegalArgumentException("Classifier: {" + this.getClassDef().getName() + + "}+ Range value is not present."); + } + final Long min = rangeValueParam.getMin(); + final Long max = rangeValueParam.getMax(); + if (min > max) { + throw new IllegalArgumentException("Range value mismatch. MIN {" + min + "} is greater than MAX {" + max + + "}."); + } + } + @Override + public List update(List matches, Map params) { Set sPorts = new HashSet<>(); Set dPorts = new HashSet<>(); - // int-value and range parameters - param = params.get(SPORT); - if (param != null && (param instanceof Long)) - sPorts.add((long) param); - param = params.get(DPORT); - if (param != null && (param instanceof Long)) - dPorts.add((long) param); - param = params.get(SPORT_RANGE); - if (param != null && param instanceof RangeValue) { - sPorts.addAll(createSetFromRange((RangeValue) param)); - } - param = params.get(DPORT_RANGE); - if (param != null && param instanceof RangeValue) { - dPorts.addAll(createSetFromRange((RangeValue) param)); - } - - Set l4Matches = null; - if ("UDP".equals(type)) { - l4Matches = createUdpMatches(sPorts, dPorts); - } else { - l4Matches = createTcpMatches(sPorts, dPorts); + if (params.get(SPORT) != null) { + sPorts.add(params.get(SPORT).getIntValue()); + } else if (params.get(SPORT_RANGE) != null) { + sPorts.addAll(createSetFromRange(params.get(SPORT_RANGE).getRangeValue())); + } + if (params.get(DPORT) != null) { + dPorts.add(params.get(DPORT).getIntValue()); + } else if (params.get(DPORT_RANGE) != null) { + dPorts.addAll(createSetFromRange(params.get(DPORT_RANGE).getRangeValue())); } + List newMatches = new ArrayList<>(); for (MatchBuilder matchBuilder : matches) { - Match baseMatch = matchBuilder.build(); - for (Layer4Match l4Match : l4Matches) { - newMatches.add(new MatchBuilder(baseMatch).setLayer4Match(l4Match)); + Layer4Match l4Match = matchBuilder.getLayer4Match(); + Set l4Matches = null; + if (l4Match == null) { + l4Match = resolveL4Match(params); + } + if (l4Match instanceof UdpMatch) { + l4Matches = createUdpMatches((UdpMatch) l4Match, sPorts, dPorts); + } else if (l4Match instanceof TcpMatch) { + l4Matches = createTcpMatches((TcpMatch) l4Match, sPorts, dPorts); + } else if (l4Match instanceof SctpMatch) { + l4Matches = createSctpMatches((SctpMatch) l4Match, sPorts, dPorts); + } + for (Layer4Match newL4Match : l4Matches) { + newMatches.add(new MatchBuilder(matchBuilder.build()).setLayer4Match(newL4Match)); } } return newMatches; } - private Set createSetFromRange(RangeValue rangeValueParam){ + private Layer4Match resolveL4Match(Map params) { + Long ipProto = IpProtoClassifier.getIpProtoValue(params); + if (ipProto == null) { + throw new IllegalArgumentException("Classifier-instance " + this.getClassDef().getName() + + ": L4 protocol is null."); + } + if (IpProtoClassifier.UDP.equals(ipProto)) { + return new UdpMatchBuilder().build(); + } else if (IpProtoClassifier.TCP.equals(ipProto)) { + return new TcpMatchBuilder().build(); + } else if (IpProtoClassifier.SCTP.equals(ipProto)) { + return new SctpMatchBuilder().build(); + } + throw new IllegalArgumentException("Unsupported L4 protocol."); + } + + private Set createSetFromRange(RangeValue rangeValueParam) { Set res = new HashSet<>(); if (rangeValueParam != null) { final Long min = rangeValueParam.getMin(); final Long max = rangeValueParam.getMax(); - if (min <= max) { - for (long val = min; val <= max; val++) { - res.add(val); - } - } else { - LOG.warn("Range value mismatch. MIN {} is greater than MAX {}.", min, max); + for (long val = min; val <= max; val++) { + res.add(val); } } return res; } - private Set createUdpMatches(Set sPorts, Set dPorts) { + private Set createUdpMatches(UdpMatch udpMatch, Set sPorts, Set dPorts) { Set udpMatches = new HashSet<>(); if (!sPorts.isEmpty() && dPorts.isEmpty()) { for (Long srcPort : sPorts) { - udpMatches.add(new UdpMatchBuilder().setUdpSourcePort(new PortNumber(srcPort.intValue())).build()); + equalOrNotSetValidation(udpMatch.getUdpSourcePort(), srcPort.longValue()); + udpMatches.add(new UdpMatchBuilder(udpMatch).setUdpSourcePort(new PortNumber(srcPort.intValue())).build()); } } else if (sPorts.isEmpty() && !dPorts.isEmpty()) { for (Long dstPort : dPorts) { - udpMatches.add(new UdpMatchBuilder().setUdpDestinationPort(new PortNumber(dstPort.intValue())).build()); + equalOrNotSetValidation(udpMatch.getUdpDestinationPort(), dstPort.longValue()); + udpMatches.add(new UdpMatchBuilder(udpMatch).setUdpDestinationPort(new PortNumber(dstPort.intValue())) + .build()); } } else if (!sPorts.isEmpty() && !dPorts.isEmpty()) { for (Long srcPort : sPorts) { for (Long dstPort : dPorts) { - udpMatches.add(new UdpMatchBuilder().setUdpSourcePort(new PortNumber(srcPort.intValue())) - .setUdpDestinationPort(new PortNumber(dstPort.intValue())).build()); + equalOrNotSetValidation(udpMatch.getUdpSourcePort(), srcPort.longValue()); + equalOrNotSetValidation(udpMatch.getUdpDestinationPort(), dstPort.longValue()); + udpMatches.add(new UdpMatchBuilder(udpMatch).setUdpSourcePort(new PortNumber(srcPort.intValue())) + .setUdpDestinationPort(new PortNumber(dstPort.intValue())) + .build()); } } } return udpMatches; } - private Set createTcpMatches(Set sPorts, Set dPorts) { + private Set createTcpMatches(TcpMatch tcpMatch, Set sPorts, Set dPorts) { Set tcpMatches = new HashSet<>(); if (!sPorts.isEmpty() && dPorts.isEmpty()) { for (Long srcPort : sPorts) { - tcpMatches.add(new TcpMatchBuilder().setTcpSourcePort(new PortNumber(srcPort.intValue())).build()); + equalOrNotSetValidation(tcpMatch.getTcpSourcePort(), srcPort.longValue()); + tcpMatches.add(new TcpMatchBuilder(tcpMatch).setTcpSourcePort(new PortNumber(srcPort.intValue())).build()); } } else if (sPorts.isEmpty() && !dPorts.isEmpty()) { for (Long dstPort : dPorts) { - tcpMatches - .add(new TcpMatchBuilder().setTcpDestinationPort(new PortNumber(dstPort.intValue())).build()); + equalOrNotSetValidation(tcpMatch.getTcpDestinationPort(), dstPort.longValue()); + tcpMatches.add(new TcpMatchBuilder(tcpMatch).setTcpDestinationPort(new PortNumber(dstPort.intValue())) + .build()); } } else if (!sPorts.isEmpty() && !dPorts.isEmpty()) { for (Long srcPort : sPorts) { for (Long dstPort : dPorts) { - tcpMatches.add(new TcpMatchBuilder().setTcpSourcePort(new PortNumber(srcPort.intValue())) - .setTcpDestinationPort(new PortNumber(dstPort.intValue())).build()); + equalOrNotSetValidation(tcpMatch.getTcpSourcePort(), srcPort.longValue()); + equalOrNotSetValidation(tcpMatch.getTcpDestinationPort(), dstPort.longValue()); + tcpMatches.add(new TcpMatchBuilder(tcpMatch).setTcpSourcePort(new PortNumber(srcPort.intValue())) + .setTcpDestinationPort(new PortNumber(dstPort.intValue())) + .build()); } } } return tcpMatches; } + + private Set createSctpMatches(SctpMatch sctpMatch, Set sPorts, Set dPorts) { + Set sctpMatches = new HashSet<>(); + if (!sPorts.isEmpty() && dPorts.isEmpty()) { + for (Long srcPort : sPorts) { + equalOrNotSetValidation(sctpMatch.getSctpSourcePort(), srcPort.longValue()); + sctpMatches.add(new SctpMatchBuilder(sctpMatch).setSctpSourcePort(new PortNumber(srcPort.intValue())) + .build()); + } + } else if (sPorts.isEmpty() && !dPorts.isEmpty()) { + for (Long dstPort : dPorts) { + equalOrNotSetValidation(sctpMatch.getSctpDestinationPort(), dstPort.longValue()); + sctpMatches.add(new SctpMatchBuilder(sctpMatch).setSctpDestinationPort(new PortNumber(dstPort.intValue())) + .build()); + } + } else if (!sPorts.isEmpty() && !dPorts.isEmpty()) { + for (Long srcPort : sPorts) { + for (Long dstPort : dPorts) { + equalOrNotSetValidation(sctpMatch.getSctpSourcePort(), srcPort.longValue()); + equalOrNotSetValidation(sctpMatch.getSctpDestinationPort(), dstPort.longValue()); + sctpMatches.add(new SctpMatchBuilder(sctpMatch).setSctpSourcePort(new PortNumber(srcPort.intValue())) + .setSctpDestinationPort(new PortNumber(dstPort.intValue())) + .build()); + } + } + } + return sctpMatches; + } + + private void equalOrNotSetValidation(PortNumber portInMatch, long paramValue) { + if (portInMatch != null) { + if (paramValue != portInMatch.getValue().longValue()) { + throw new IllegalArgumentException("Classification conflict at " + this.getClassDef().getName() + + ": Trying to override port value: " + portInMatch.getValue().longValue() + " by value " + + paramValue); + } + } + } + + @Override + public void checkPrereqs(List matches) { + for (MatchBuilder match : matches) { + Long proto = null; + try { + proto = Long.valueOf(match.getIpMatch().getIpProtocol().longValue()); + } catch (NullPointerException e) { + throw new IllegalArgumentException("Ip proto match is missing."); + } + if (!IpProtoClassifier.TCP.equals(proto) && !IpProtoClassifier.UDP.equals(proto) + && !IpProtoClassifier.SCTP.equals(proto)) { + throw new IllegalArgumentException("Unsupported proto value.\n" + "Classifier: " + + this.getClass().getName() + ", proto set: " + proto); + } + } + } } diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ParamDerivator.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ParamDerivator.java new file mode 100644 index 000000000..99b60df9d --- /dev/null +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ParamDerivator.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; + +public abstract class ParamDerivator { + + /** + * It is possible to derive missing parameters. + *

+ * Examle: + *

+ * Ether-type parameter is missing. Derivation policy might instruct: ipv4 and ipv6 flows need + * to be created if ether-type parameter is not present. In this case two derivations of + * {@code params} should be returned. One with ipv4 ether-type, the other with ipv6. + * + * @param params parameters inserted by user + * @return list of {@code params} updated with derived values + */ + public abstract List> deriveParameter(Map params); + + public static final ParamDerivator ETHER_TYPE_DERIVATOR = new ParamDerivator() { + + @Override + public List> deriveParameter(Map params) { + + if (!params.containsKey(EtherTypeClassifier.ETHER_TYPE)) { + Map ipv4Params = new HashMap<>(params); + Map ipv6Params = new HashMap<>(params); + ipv4Params.put(EtherTypeClassifier.ETHER_TYPE, new ParameterValueBuilder().setIntValue(FlowUtils.IPv4) + .build()); + ipv6Params.put(EtherTypeClassifier.ETHER_TYPE, new ParameterValueBuilder().setIntValue(FlowUtils.IPv6) + .build()); + List> derivedParams = new ArrayList<>(); + derivedParams.add(ipv4Params); + derivedParams.add(ipv6Params); + return derivedParams; + } + return Collections.singletonList(params); + } + }; +} diff --git a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/SubjectFeatures.java b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/SubjectFeatures.java index 7ad60df97..3840f3f8f 100644 --- a/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/SubjectFeatures.java +++ b/renderers/ofoverlay/src/main/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/SubjectFeatures.java @@ -12,13 +12,10 @@ import java.util.List; import java.util.Map; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinition; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ActionDefinitionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition; import com.google.common.base.Function; @@ -32,12 +29,12 @@ import com.google.common.collect.ImmutableMap; public class SubjectFeatures { private static final Map classifiers = ImmutableMap. - of(EtherTypeClassifier.ID, new EtherTypeClassifier(), - IpProtoClassifier.ID, new IpProtoClassifier(), - L4Classifier.ID, new L4Classifier()); + of(EtherTypeClassifier.ID, Classifier.ETHER_TYPE_CL, + IpProtoClassifier.ID, Classifier.IP_PROTO_CL, + L4Classifier.ID, Classifier.L4_CL); private static final List classifierDefs = - ImmutableList.copyOf(Collections2.transform(classifiers.values(), + ImmutableList.copyOf(Collections2.transform(classifiers.values(), new Function() { @Override public ClassifierDefinition apply(Classifier input) { @@ -45,7 +42,7 @@ public class SubjectFeatures { } } )); - + private static final Map actions = ImmutableMap. of(AllowAction.ID, new AllowAction()); @@ -60,7 +57,6 @@ public class SubjectFeatures { } )); - public static final SubjectFeatureDefinitions OF_OVERLAY_FEATURES = new SubjectFeatureDefinitionsBuilder() .setActionDefinition(actionDefs) @@ -68,10 +64,10 @@ public class SubjectFeatures { .build(); /** - * Get the {@link Classifier} associated with the given + * Get the {@link Classifier} associated with the given * {@link ClassifierDefinitionId} * @param id the {@link ClassifierDefinitionId} to look up - * @return the {@link Classifier} if one exists, or null + * @return the {@link Classifier} if one exists, or null * otherwise */ public static Classifier getClassifier(ClassifierDefinitionId id) { @@ -88,5 +84,4 @@ public class SubjectFeatures { public static Action getAction(ActionDefinitionId id) { return actions.get(id); } - } diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OfTableTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OfTableTest.java index e0a5b2d83..b17756d26 100644 --- a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OfTableTest.java +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/flow/OfTableTest.java @@ -61,19 +61,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import com.google.common.collect.ImmutableList; public class OfTableTest { - OfContext ctx; + OfContext ctx; MockEndpointManager endpointManager; MockPolicyResolver policyResolver; MockPolicyManager policyManager; MockSwitchManager switchManager; - + NodeId nodeId = new NodeId("openflow:1"); NodeId remoteNodeId = new NodeId("openflow:2"); - NodeConnectorId nodeConnectorId = + NodeConnectorId nodeConnectorId = new NodeConnectorId(nodeId.getValue() + ":4"); - NodeConnectorId tunnelId = + NodeConnectorId tunnelId = new NodeConnectorId(nodeId.getValue() + ":42"); L3ContextId l3c = new L3ContextId("2cf51ee4-e996-467e-a277-2d380334a91d"); @@ -86,19 +86,19 @@ public class OfTableTest { EndpointGroupId eg = new EndpointGroupId("36dec84a-08c7-497b-80b6-a0035af72a12"); EndpointGroupId eg2 = new EndpointGroupId("632e5e11-7988-4eb5-8fe6-6c182d890276"); ContractId cid = new ContractId("a5874893-bcd5-46de-96af-3c8d99bedf9f"); - + protected void initCtx() { endpointManager = new MockEndpointManager(); policyResolver = new MockPolicyResolver(); policyManager = new MockPolicyManager(policyResolver, endpointManager); switchManager = new MockSwitchManager(); - + ctx = new OfContext(null, - null, - policyManager, - policyResolver, - switchManager, - endpointManager, + null, + policyManager, + policyResolver, + switchManager, + endpointManager, null); } @@ -163,8 +163,8 @@ public class OfTableTest { .setIntValue(Long.valueOf(80)) .build(), new ParameterValueBuilder() - .setName(new ParameterName("type")) - .setStringValue("TCP") + .setName(new ParameterName("proto")) + .setIntValue(Long.valueOf(6)) .build())) .build())) .setActionInstance(ImmutableList.of(new ActionInstanceBuilder() @@ -181,7 +181,7 @@ public class OfTableTest { .build())) .build())); } - + protected SubjectBuilder baseSubject(Direction direction) { return new SubjectBuilder() .setName(new SubjectName("s1")) diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierTest.java new file mode 100644 index 000000000..d9d461c17 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + +import static org.junit.Assert.*; + +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +public class ClassifierTest { + + List matches; + Map params; + + @Before + public void setUp() { + matches = new ArrayList<>(Collections.singletonList(new MatchBuilder())); + params = new HashMap<>(); + } + + @Test + public void updateMatchTest() { + + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createIntValueParam(EtherTypeClassifier.ETHER_TYPE, FlowUtils.IPv4)); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.SPORT, 80)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + ClassificationResult result = Classifier.L4_CL.updateMatch(matches, params); + assertEquals(true, result.isSuccessfull()); + assertEquals(3, result.getMatchBuilders().size()); + Set dstPorts = new HashSet<>(); + for (MatchBuilder match : result.getMatchBuilders()) { + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(match.getEthernetMatch().getEthernetType())); + assertEquals(true, new TcpMatchBuilder((TcpMatch) match.getLayer4Match()).getTcpSourcePort() + .getValue() + .intValue() == 80); + dstPorts.add(Long.valueOf(new TcpMatchBuilder((TcpMatch) match.getLayer4Match()).getTcpDestinationPort() + .getValue() + .longValue())); + } + for (Long i = dstRangeStart; i <= dstRangeEnd; i++) { + assertEquals(true, dstPorts.contains((i))); + } + } +} diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierTestUtils.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierTestUtils.java new file mode 100644 index 000000000..0b8f4a740 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/ClassifierTestUtils.java @@ -0,0 +1,97 @@ +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + +import java.util.Map; + +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder; + +import com.google.common.collect.ImmutableMap; + +public class ClassifierTestUtils { + + static final EthernetType IPV4_ETH_TYPE = new EthernetTypeBuilder().setType(new EtherType(FlowUtils.IPv4)).build(); + static final EthernetType IPV6_ETH_TYPE = new EthernetTypeBuilder().setType(new EtherType(FlowUtils.IPv6)).build(); + + static final Long TCP = Long.valueOf(6); + static final Long UDP = Long.valueOf(17); + static final Long SCTP = Long.valueOf(132); + + static Map createRangeValueParam(String paramName, long min, long max) { + return ImmutableMap. of(paramName, + new ParameterValueBuilder() + .setRangeValue(new RangeValueBuilder() + .setMin(min) + .setMax(max) + .build()) + .build()); + } + + static Map createIntValueParam(String paramName, long value) { + return ImmutableMap. of(paramName, + new ParameterValueBuilder() + .setIntValue(value) + .build()); + } + + static final EthernetMatch createEthernetMatch(EthernetType ethType) { + return new EthernetMatchBuilder() + .setEthernetType(ethType) + .build(); + } + + static final IpMatch createIpMatch(short ipProtoValue) { + return new IpMatchBuilder() + .setIpProtocol(ipProtoValue) + .build(); + } + + static final Layer4Match createUdpDstPort(int portNumber) { + return new UdpMatchBuilder() + .setUdpDestinationPort(new PortNumber(portNumber)) + .build(); + } + + static final Layer4Match createUdpSrcPort(int portNumber) { + return new UdpMatchBuilder() + .setUdpSourcePort(new PortNumber(portNumber)) + .build(); + } + + final Layer4Match createTcpDstPort(int portNumber) { + return new TcpMatchBuilder() + .setTcpDestinationPort(new PortNumber(portNumber)) + .build(); + } + + final Layer4Match createTcpSrcPort(int portNumber) { + return new TcpMatchBuilder() + .setTcpSourcePort(new PortNumber(portNumber)) + .build(); + } + + final static Layer4Match createSctpDstPort(int portNumber) { + return new SctpMatchBuilder() + .setSctpDestinationPort(new PortNumber(portNumber)) + .build(); + } + + final static Layer4Match createSctpSrcPort(int portNumber) { + return new SctpMatchBuilder() + .setSctpSourcePort(new PortNumber(portNumber)) + .build(); + } +} \ No newline at end of file diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/EtherTypeClassifierTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/EtherTypeClassifierTest.java new file mode 100644 index 000000000..7ccc63b31 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/EtherTypeClassifierTest.java @@ -0,0 +1,83 @@ +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; + +import com.google.common.collect.ImmutableMap; + +public class EtherTypeClassifierTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + List matches; + Map params; + + @Before + public void setUp() { + matches = new ArrayList<>(); + params = new HashMap<>(); + } + + @Test + public void setValueTest() { + matches.add(new MatchBuilder() + .setIpMatch(ClassifierTestUtils.createIpMatch(ClassifierTestUtils.TCP.shortValue()))); + params.putAll(ClassifierTestUtils.createIntValueParam(EtherTypeClassifier.ETHER_TYPE, FlowUtils.IPv4)); + matches = Classifier.ETHER_TYPE_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + assertEquals(true, ClassifierTestUtils.TCP.equals(matches.get(0).getIpMatch().getIpProtocol().longValue())); + } + + @Test + public void overrideByTheSameValueTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV6_ETH_TYPE)) + .setIpMatch(ClassifierTestUtils.createIpMatch(ClassifierTestUtils.UDP.shortValue()))); + params.putAll(ClassifierTestUtils.createIntValueParam(EtherTypeClassifier.ETHER_TYPE, FlowUtils.IPv6)); + matches = Classifier.ETHER_TYPE_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV6_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + assertEquals(true, ClassifierTestUtils.UDP.equals(matches.get(0).getIpMatch().getIpProtocol().longValue())); + } + + @Test + public void overrideByDifferentValueTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE)) + .setIpMatch(ClassifierTestUtils.createIpMatch(ClassifierTestUtils.SCTP.shortValue()))); + params.putAll(ClassifierTestUtils.createIntValueParam(EtherTypeClassifier.ETHER_TYPE, FlowUtils.IPv6)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Trying to override ether-type value:"); + matches = Classifier.ETHER_TYPE_CL.update(matches, params); + } + + @Test + public void checkPresenceOfRequiredParameters1Test() { + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Parameter ethertype not present"); + Classifier.ETHER_TYPE_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void checkPresenceOfRequiredParameters2Test() { + params.putAll(ImmutableMap. of(EtherTypeClassifier.ETHER_TYPE, + new ParameterValueBuilder().build())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Value of ethertype parameter is not present"); + Classifier.ETHER_TYPE_CL.checkPresenceOfRequiredParams(params); + } +} diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/IpProtoClassifierTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/IpProtoClassifierTest.java new file mode 100644 index 000000000..d106fd6d5 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/IpProtoClassifierTest.java @@ -0,0 +1,83 @@ +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; + +import com.google.common.collect.ImmutableMap; + +public class IpProtoClassifierTest { + + List matches; + Map params; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Before + public void setUp() { + matches = new ArrayList<>(); + params = new HashMap<>(); + } + + @Test + public void setValueTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE))); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + matches = Classifier.IP_PROTO_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + assertEquals(true, ClassifierTestUtils.TCP.equals(matches.get(0).getIpMatch().getIpProtocol().longValue())); + } + + @Test + public void overrideByTheSameValueTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV6_ETH_TYPE)) + .setIpMatch(ClassifierTestUtils.createIpMatch(ClassifierTestUtils.UDP.shortValue()))); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.UDP)); + matches = Classifier.IP_PROTO_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV6_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + assertEquals(true, ClassifierTestUtils.UDP.equals(matches.get(0).getIpMatch().getIpProtocol().longValue())); + } + + @Test + public void overrideByDifferentValueTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE)) + .setIpMatch(ClassifierTestUtils.createIpMatch(ClassifierTestUtils.SCTP.shortValue()))); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Trying to override proto value"); + matches = Classifier.IP_PROTO_CL.update(matches, params); + } + + @Test + public void checkPresenceOfRequiredParameters1Test() { + params.putAll(ClassifierTestUtils.createIntValueParam(EtherTypeClassifier.ETHER_TYPE, FlowUtils.IPv4)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Parameter proto not present"); + Classifier.IP_PROTO_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void checkPresenceOfRequiredParameters2Test() { + params.putAll(ImmutableMap. of(IpProtoClassifier.PROTO, + new ParameterValueBuilder().build())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Value of proto parameter is not present"); + Classifier.IP_PROTO_CL.checkPresenceOfRequiredParams(params); + } +} diff --git a/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/L4ClassifierTest.java b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/L4ClassifierTest.java new file mode 100644 index 000000000..08d52df03 --- /dev/null +++ b/renderers/ofoverlay/src/test/java/org/opendaylight/groupbasedpolicy/renderer/ofoverlay/sf/L4ClassifierTest.java @@ -0,0 +1,344 @@ +package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder; + +import com.google.common.collect.ImmutableMap; + +public class L4ClassifierTest { + + List matches; + Map params; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Before + public void setUp() { + params = new HashMap<>(); + matches = new ArrayList<>(); + } + + @Test + public void setTcpSrcPortTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE))); + Long sPort = Long.valueOf(80); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.SPORT, sPort)); + matches = Classifier.L4_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + TcpMatch match = new TcpMatchBuilder((TcpMatch) matches.get(0).getLayer4Match()).build(); + assertEquals(true, sPort.equals(match.getTcpSourcePort().getValue().longValue())); + assertEquals(true, match.getTcpDestinationPort() == null); + } + + @Test + public void setTcpDstPortTest() { + Long dPort = Long.valueOf(80); + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV6_ETH_TYPE))); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.DPORT, dPort)); + matches = Classifier.L4_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV6_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + TcpMatch match = new TcpMatchBuilder((TcpMatch) matches.get(0).getLayer4Match()).build(); + assertEquals(true, dPort.equals(match.getTcpDestinationPort().getValue().longValue())); + assertEquals(true, match.getTcpSourcePort() == null); + } + + @Test + public void setTcpSrcPortDstPortRangeTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE))); + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + Long srcPort = Long.valueOf(80); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.SPORT, srcPort)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + matches = Classifier.L4_CL.update(matches, params); + Set dstPorts = new HashSet<>(); + for (MatchBuilder match : matches) { + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(match.getEthernetMatch().getEthernetType())); + assertEquals(true, + Long.valueOf(new TcpMatchBuilder((TcpMatch) match.getLayer4Match()).getTcpSourcePort().getValue()) + .equals(srcPort)); + dstPorts.add(new TcpMatchBuilder((TcpMatch) match.getLayer4Match()).getTcpDestinationPort().getValue() + .longValue()); + } + for (Long i = dstRangeStart; i <= dstRangeEnd; i++) { + assertEquals(true, dstPorts.contains((i))); + } + } + + @Test + public void overrideDstPortWithTheSameValueTest() { + Long dPort = Long.valueOf(80); + matches.add(new MatchBuilder() + .setLayer4Match(ClassifierTestUtils.createUdpDstPort(80)) + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV6_ETH_TYPE))); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.UDP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.DPORT, dPort)); + matches = Classifier.L4_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV6_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + UdpMatch match = new UdpMatchBuilder((UdpMatch) matches.get(0).getLayer4Match()).build(); + assertEquals(true, dPort.equals(match.getUdpDestinationPort().getValue().longValue())); + assertEquals(true, match.getUdpSourcePort() == null); + } + + @Test + public void addUdpSrcPortRangeTest() { + matches.add(new MatchBuilder() + .setLayer4Match(ClassifierTestUtils.createUdpDstPort(80)) + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE))); + Long srcRangeStart = Long.valueOf(8079); + Long srcRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.UDP)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.SPORT_RANGE, srcRangeStart, srcRangeEnd)); + matches = Classifier.L4_CL.update(matches, params); + Set srcPorts = new HashSet<>(); + for (MatchBuilder match : matches) { + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(match.getEthernetMatch().getEthernetType())); + assertEquals(true, new UdpMatchBuilder((UdpMatch) match.getLayer4Match()).getUdpDestinationPort() + .getValue().intValue() == 80); + assertEquals(true, new UdpMatchBuilder((UdpMatch) match.getLayer4Match()).getUdpDestinationPort() + .getValue() + .longValue() == 80); + srcPorts.add(new UdpMatchBuilder((UdpMatch) match.getLayer4Match()).getUdpSourcePort().getValue() + .longValue()); + } + for (Long i = srcRangeStart; i <= srcRangeEnd; i++) { + assertEquals(true, srcPorts.contains((i))); + } + } + + @Test + public void setUdpSrcPortRangeDstPortTest() { + matches.add(new MatchBuilder() + .setLayer4Match(ClassifierTestUtils.createUdpDstPort(80)) + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV6_ETH_TYPE))); + Long dPort = Long.valueOf(80); + Long srcRangeStart = Long.valueOf(8079); + Long srcRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.UDP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.DPORT, dPort)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.SPORT_RANGE, srcRangeStart, srcRangeEnd)); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + matches = Classifier.L4_CL.update(matches, params); + Set srcPorts = new HashSet<>(); + for (MatchBuilder match : matches) { + assertEquals(true, ClassifierTestUtils.IPV6_ETH_TYPE.equals(match.getEthernetMatch().getEthernetType())); + assertEquals( + true, + dPort.equals(new UdpMatchBuilder((UdpMatch) match.getLayer4Match()).getUdpDestinationPort() + .getValue().longValue())); + srcPorts.add(Long.valueOf(new UdpMatchBuilder((UdpMatch) match.getLayer4Match()).getUdpSourcePort() + .getValue().longValue())); + } + for (Long i = srcRangeStart; i <= srcRangeEnd; i++) { + assertEquals(true, srcPorts.contains((i))); + } + } + + @Test + public void overrideSrcPortWithTheSameValueTest() { + Long sPort = Long.valueOf(80); + matches.add(new MatchBuilder() + .setLayer4Match(ClassifierTestUtils.createSctpSrcPort(sPort.intValue())) + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE))); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.SCTP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.SPORT, sPort)); + matches = Classifier.L4_CL.update(matches, params); + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(matches.get(0).getEthernetMatch().getEthernetType())); + SctpMatch match = new SctpMatchBuilder((SctpMatch) matches.get(0).getLayer4Match()).build(); + assertEquals(true, sPort.equals(match.getSctpSourcePort().getValue().longValue())); + assertEquals(true, match.getSctpDestinationPort() == null); + } + + @Test + public void addSctpDstPortRangeTest() { + matches.add(new MatchBuilder() + .setLayer4Match(ClassifierTestUtils.createSctpSrcPort(80)) + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE))); + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.SCTP)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + matches = Classifier.L4_CL.update(matches, params); + Set dstPorts = new HashSet<>(); + for (MatchBuilder match : matches) { + assertEquals(true, ClassifierTestUtils.IPV4_ETH_TYPE.equals(match.getEthernetMatch().getEthernetType())); + assertEquals(true, new SctpMatchBuilder((SctpMatch) match.getLayer4Match()).getSctpSourcePort().getValue() + .intValue() == 80); + dstPorts.add(Long.valueOf(new SctpMatchBuilder((SctpMatch) match.getLayer4Match()).getSctpDestinationPort() + .getValue().longValue())); + } + for (Long i = dstRangeStart; i <= dstRangeEnd; i++) { + assertEquals(true, dstPorts.contains((i))); + } + } + + @Test + public void setSctpSrcPortRangeDstPortRangeTest() { + matches.add(new MatchBuilder() + .setEthernetMatch(ClassifierTestUtils.createEthernetMatch(ClassifierTestUtils.IPV4_ETH_TYPE))); + Long srcRangeStart = Long.valueOf(79); + Long srcRangeEnd = Long.valueOf(81); + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.SCTP)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.SPORT_RANGE, srcRangeStart, srcRangeEnd)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + matches = Classifier.L4_CL.update(matches, params); + Set> set = new HashSet<>(); + for (MatchBuilder match : matches) { + Long srcPort = Long.valueOf(new SctpMatchBuilder((SctpMatch) match.getLayer4Match()).getSctpSourcePort() + .getValue().longValue()); + Long dstPort = Long.valueOf(new SctpMatchBuilder((SctpMatch) match.getLayer4Match()) + .getSctpDestinationPort().getValue().longValue()); + set.add(Pair.of(srcPort, dstPort)); + } + for (Long i = srcRangeStart; i <= srcRangeEnd; i++) { + for (Long j = dstRangeStart; j <= dstRangeEnd; j++) { + assertEquals(true, set.contains(Pair.of(i, j))); + } + } + } + + @Test + public void srcPortSrtPortRangeMutualExclusionTest() { + matches.add(new MatchBuilder()); + Long srcRangeStart = Long.valueOf(8079); + Long srcRangeEnd = Long.valueOf(8081); + Long srcPort = Long.valueOf(80); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.SCTP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.SPORT, srcPort)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.SPORT_RANGE, srcRangeStart, srcRangeEnd)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Illegal source port parameters"); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void dstPortSrtPortRangeMutualExclusionTest() { + matches.add(new MatchBuilder()); + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + Long dstPort = Long.valueOf(80); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.UDP)); + params.putAll(ClassifierTestUtils.createIntValueParam(L4Classifier.DPORT, dstPort)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Illegal destination port parameters"); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void rangeValueMismatchTest() { + matches.add(new MatchBuilder()); + Long dstRangeStart = Long.valueOf(8081); + Long dstRangeEnd = Long.valueOf(8079); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.TCP)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Range value mismatch"); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void unsupportedProtocolTest() { + matches.add(new MatchBuilder()); + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, 136)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Unsupported L4 protocol."); + matches = Classifier.L4_CL.update(matches, params); + } + + @Test + public void classificationConflictTest() { + matches.add(new MatchBuilder() + .setLayer4Match(ClassifierTestUtils.createSctpDstPort(80))); + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createIntValueParam(IpProtoClassifier.PROTO, ClassifierTestUtils.UDP)); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Classification conflict"); + matches = Classifier.L4_CL.update(matches, params); + } + + @Test + public void noProtoTest() { + matches.add(new MatchBuilder()); + Long dstRangeStart = Long.valueOf(8079); + Long dstRangeEnd = Long.valueOf(8081); + params.putAll(ClassifierTestUtils.createRangeValueParam(L4Classifier.DPORT_RANGE, dstRangeStart, dstRangeEnd)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("L4 protocol is null."); + matches = Classifier.L4_CL.update(matches, params); + } + + @Test + public void checkPresenceOfRequiredParameters1Test() { + params.putAll(ImmutableMap. of(L4Classifier.SPORT, + new ParameterValueBuilder().build())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Value of sourceport parameter is not present"); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void checkPresenceOfRequiredParameters2Test() { + params.putAll(ImmutableMap. of(L4Classifier.DPORT, + new ParameterValueBuilder().build())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Value of destport parameter is not present"); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void checkPresenceOfRequiredParameters3Test() { + params.putAll(ImmutableMap. of(L4Classifier.SPORT_RANGE, + new ParameterValueBuilder().build())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Range value is not present"); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + } + + @Test + public void checkPresenceOfRequiredParameters4Test() { + params.putAll(ImmutableMap. of(L4Classifier.DPORT_RANGE, + new ParameterValueBuilder().build())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Range value is not present"); + Classifier.L4_CL.checkPresenceOfRequiredParams(params); + } + +} diff --git a/util/dockerTestOfOverlay/policy_config.py b/util/dockerTestOfOverlay/policy_config.py index 31436a973..32c99aa9e 100644 --- a/util/dockerTestOfOverlay/policy_config.py +++ b/util/dockerTestOfOverlay/policy_config.py @@ -10,16 +10,16 @@ tenants = [ {'name': 'http-dest', 'classifier-definition-id': '4250ab32-e8b8-445a-aebb-e1bd2cdd291f', 'parameter-value': [ - {'name': 'type', - 'string-value': 'TCP'}, + {'name': 'proto', + 'int-value': '6'}, {'name': 'destport', 'int-value': '80'} ]}, {'name': 'http-src', 'classifier-definition-id': '4250ab32-e8b8-445a-aebb-e1bd2cdd291f', 'parameter-value': [ - {'name': 'type', - 'string-value': 'TCP'}, + {'name': 'proto', + 'int-value': '6'}, {'name': 'sourceport', 'int-value': '80'} ]},