This commit solves bug 2883.
Change-Id: I1b5b886734833bd30129c71be78eb3a5af4387a8
Signed-off-by: Tomas Cechvala <tcechval@cisco.com>
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;
@Override
public void sync(ReadWriteTransaction t, InstanceIdentifier<Table> tiid,
- Map<String, FlowCtx> flowMap, NodeId nodeId,
+ Map<String, FlowCtx> flowMap, NodeId nodeId,
PolicyInfo policyInfo, Dirty dirty)
throws Exception {
dropFlow(t, tiid, flowMap, Integer.valueOf(1), null);
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)) {
for (Endpoint src : ctx.getEndpointManager().getEPsForNode(nodeId, sepg)) {
if (src.getTenant() == null || src.getEndpointGroup() == null)
continue;
-
- List<ConditionName> conds =
+
+ List<ConditionName> conds =
ctx.getEndpointManager().getCondsForEndpoint(src);
ConditionGroup scg = policyInfo.getEgCondGroup(sepg, conds);
int scgId = ctx.getPolicyManager().getCondGroupOrdinal(scg);
-
+
Set<EgKey> 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<Table> tiid,
Map<String, FlowCtx> flowMap, NodeId nodeId,
int sepgId) {
.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()
writeFlow(t, tiid, flow.build());
}
}
-
- private void allowFromTunnel(ReadWriteTransaction t,
+
+ private void allowFromTunnel(ReadWriteTransaction t,
InstanceIdentifier<Table> tiid,
Map<String, FlowCtx> flowMap, NodeId nodeId) {
NodeConnectorId tunPort =
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)
writeFlow(t, tiid, flow.build());
}
}
-
- private void syncPolicy(ReadWriteTransaction t,
+
+ private void syncPolicy(ReadWriteTransaction t,
InstanceIdentifier<Table> tiid,
Map<String, FlowCtx> 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<RuleGroup> rgs = policy.getRules(scg, dcg);
-
+
int priority = 65000;
for (RuleGroup rg : rgs) {
TenantId tenantId = rg.getContractTenant().getId();
p, r, Direction.In, priority);
syncDirection(t, tiid, flowMap, nodeId, tenant,
p, r, Direction.Out, priority);
-
+
priority -= 1;
}
}
}
- private void syncDirection(ReadWriteTransaction t,
+ private void syncDirection(ReadWriteTransaction t,
InstanceIdentifier<Table> tiid,
Map<String, FlowCtx> flowMap, NodeId nodeId,
IndexedTenant contractTenant,
abl = act.updateAction(abl, new HashMap<String,Object>(), 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.
.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)),
.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;
}
.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<MatchBuilder> matches = Collections.singletonList(baseMatch);
- Map<String,Object> params = new HashMap<>();
+ Map<String,ParameterValue> 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<Map<String, ParameterValue>> derivedParams = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(params);
+ for (Map<String, ParameterValue> flowParams : derivedParams) {
+ List<MatchBuilder> 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
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;
--- /dev/null
+/*
+ * 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<MatchBuilder> matchBuilders;
+
+ public ClassificationResult(String errorMessage) {
+ this.message = Preconditions.checkNotNull(errorMessage);
+ this.isSuccessful = false;
+ matchBuilders = null;
+ }
+
+ public ClassificationResult(List<MatchBuilder> matches) {
+ message = "";
+ this.matchBuilders = Preconditions.checkNotNull(matches);
+ this.isSuccessful = true;
+ }
+
+ public List<MatchBuilder> 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
/*
- * 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
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<MatchBuilder> matches, Map<String, ParameterValue> params) {
+ if (params == null) {
+ return new ClassificationResult("Classifier: {" + this.getClassDef().getName() + "} No parameters present.");
+ }
+ List<MatchBuilder> matchBuilders = matches;
+ try {
+ checkPresenceOfRequiredParams(params);
+ matchBuilders = this.update(matchBuilders, params);
+ Classifier parent = this.getParent();
+ List<Classifier> 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<String, ParameterValue> params);
+
+ /**
+ * Resolves {@code matches} from inserted {@code params} and updates them.
+ * <p>
+ * 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<MatchBuilder> update(List<MatchBuilder> matches, Map<String, ParameterValue> 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<MatchBuilder> updateMatch(List<MatchBuilder> matches,
- Map<String, Object> params);
+ protected abstract void checkPrereqs(List<MatchBuilder> matches);
}
/*
- * 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
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;
* 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() {
}
@Override
- public List<MatchBuilder> updateMatch(List<MatchBuilder> matches,
- Map<String, Object> 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<String, ParameterValue> 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<MatchBuilder> update(List<MatchBuilder> matches, Map<String, ParameterValue> 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<MatchBuilder> matches) {
+ // So far EthType has no prereqs.
+ }
}
/*
- * 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
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
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<String, Object> ipv4 =
- ImmutableMap.<String,Object>of(TYPE, FlowUtils.IPv4);
- private static final Map<String, Object> ipv6 =
- ImmutableMap.<String,Object>of(TYPE, FlowUtils.IPv6);
+ protected IpProtoClassifier(Classifier parent) {
+ super(parent);
+ }
@Override
public ClassifierDefinitionId getId() {
}
@Override
- public List<MatchBuilder> updateMatch(List<MatchBuilder> matches,
- Map<String, Object> 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<MatchBuilder> 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<String, ParameterValue> 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<MatchBuilder> updateMatch(MatchBuilder match,
- Long proto,
- Map<String, Object> parentParams) {
- List<MatchBuilder> r =
- super.updateMatch(Collections.singletonList(match),
- parentParams);
- for (MatchBuilder mb : r) {
+ @Override
+ protected List<MatchBuilder> update(List<MatchBuilder> matches, Map<String, ParameterValue> 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<MatchBuilder> 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<String, ParameterValue> 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;
}
}
/*
- * 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
package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;
+
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
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<String, Object> tcp =
- ImmutableMap.<String,Object>of(PROTO, Long.valueOf(6));
- private static final Map<String, Object> udp =
- ImmutableMap.<String,Object>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;
}
@Override
- public List<MatchBuilder> updateMatch(List<MatchBuilder> matches,
- Map<String, Object> 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<String, ParameterValue> 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<MatchBuilder> update(List<MatchBuilder> matches, Map<String, ParameterValue> params) {
Set<Long> sPorts = new HashSet<>();
Set<Long> 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<? extends Layer4Match> 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<MatchBuilder> 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<? extends Layer4Match> 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<Long> createSetFromRange(RangeValue rangeValueParam){
+ private Layer4Match resolveL4Match(Map<String, ParameterValue> 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<Long> createSetFromRange(RangeValue rangeValueParam) {
Set<Long> 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<UdpMatch> createUdpMatches(Set<Long> sPorts, Set<Long> dPorts) {
+ private Set<UdpMatch> createUdpMatches(UdpMatch udpMatch, Set<Long> sPorts, Set<Long> dPorts) {
Set<UdpMatch> 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<TcpMatch> createTcpMatches(Set<Long> sPorts, Set<Long> dPorts) {
+ private Set<TcpMatch> createTcpMatches(TcpMatch tcpMatch, Set<Long> sPorts, Set<Long> dPorts) {
Set<TcpMatch> 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<SctpMatch> createSctpMatches(SctpMatch sctpMatch, Set<Long> sPorts, Set<Long> dPorts) {
+ Set<SctpMatch> 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<MatchBuilder> 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);
+ }
+ }
+ }
}
--- /dev/null
+/*
+ * 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.
+ * <p>
+ * Examle:
+ * <p>
+ * 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<Map<String, ParameterValue>> deriveParameter(Map<String, ParameterValue> params);
+
+ public static final ParamDerivator ETHER_TYPE_DERIVATOR = new ParamDerivator() {
+
+ @Override
+ public List<Map<String, ParameterValue>> deriveParameter(Map<String, ParameterValue> params) {
+
+ if (!params.containsKey(EtherTypeClassifier.ETHER_TYPE)) {
+ Map<String, ParameterValue> ipv4Params = new HashMap<>(params);
+ Map<String, ParameterValue> 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<Map<String, ParameterValue>> derivedParams = new ArrayList<>();
+ derivedParams.add(ipv4Params);
+ derivedParams.add(ipv6Params);
+ return derivedParams;
+ }
+ return Collections.singletonList(params);
+ }
+ };
+}
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;
public class SubjectFeatures {
private static final Map<ClassifierDefinitionId, Classifier> classifiers =
ImmutableMap.<ClassifierDefinitionId, Classifier>
- 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<ClassifierDefinition> classifierDefs =
- ImmutableList.copyOf(Collections2.transform(classifiers.values(),
+ ImmutableList.copyOf(Collections2.transform(classifiers.values(),
new Function<Classifier, ClassifierDefinition>() {
@Override
public ClassifierDefinition apply(Classifier input) {
}
}
));
-
+
private static final Map<ActionDefinitionId, Action> actions =
ImmutableMap.<ActionDefinitionId, Action>
of(AllowAction.ID, new AllowAction());
}
));
-
public static final SubjectFeatureDefinitions OF_OVERLAY_FEATURES =
new SubjectFeatureDefinitionsBuilder()
.setActionDefinition(actionDefs)
.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 <code>null</code>
+ * @return the {@link Classifier} if one exists, or <code>null</code>
* otherwise
*/
public static Classifier getClassifier(ClassifierDefinitionId id) {
public static Action getAction(ActionDefinitionId id) {
return actions.get(id);
}
-
}
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");
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);
}
.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()
.build()))
.build()));
}
-
+
protected SubjectBuilder baseSubject(Direction direction) {
return new SubjectBuilder()
.setName(new SubjectName("s1"))
--- /dev/null
+/*
+ * 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<MatchBuilder> matches;
+ Map<String, ParameterValue> 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<Long> 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)));
+ }
+ }
+}
--- /dev/null
+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<String, ParameterValue> createRangeValueParam(String paramName, long min, long max) {
+ return ImmutableMap.<String, ParameterValue> of(paramName,
+ new ParameterValueBuilder()
+ .setRangeValue(new RangeValueBuilder()
+ .setMin(min)
+ .setMax(max)
+ .build())
+ .build());
+ }
+
+ static Map<String, ParameterValue> createIntValueParam(String paramName, long value) {
+ return ImmutableMap.<String, ParameterValue> 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
--- /dev/null
+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<MatchBuilder> matches;
+ Map<String, ParameterValue> 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.<String, ParameterValue> 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);
+ }
+}
--- /dev/null
+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<MatchBuilder> matches;
+ Map<String, ParameterValue> 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.<String, ParameterValue> 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);
+ }
+}
--- /dev/null
+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<MatchBuilder> matches;
+ Map<String, ParameterValue> 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<Long> 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<Long> 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<Long> 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<Long> 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<Pair<Long, Long>> 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.<String, ParameterValue> 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.<String, ParameterValue> 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.<String, ParameterValue> 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.<String, ParameterValue> of(L4Classifier.DPORT_RANGE,
+ new ParameterValueBuilder().build()));
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Range value is not present");
+ Classifier.L4_CL.checkPresenceOfRequiredParams(params);
+ }
+
+}
{'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'}
]},