blob: 0791f3ac081ccb0d96c0be18b36f6ac67fcd2a32 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.pi.impl;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.tuple.Pair;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.pi.impl.CriterionTranslators.EthCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.EthTypeCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IpCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.PortCriterionTranslator;
import org.onosproject.net.pi.model.PiMatchType;
import org.onosproject.net.pi.runtime.PiExactFieldMatch;
import org.onosproject.net.pi.runtime.PiFieldMatch;
import org.onosproject.net.pi.runtime.PiHeaderFieldId;
import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
import java.util.Map;
import static java.lang.String.format;
import static org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException;
import static org.onosproject.net.pi.impl.CriterionTranslator.CriterionTranslatorException;
import static org.onosproject.net.pi.runtime.PiFlowRuleTranslationService.PiFlowRuleTranslationException;
/**
* Helper class to translate criterion instances to PI field matches.
*/
final class CriterionTranslatorHelper {
private static final Map<Class<? extends Criterion>, CriterionTranslator> TRANSLATORS = ImmutableMap.of(
// Add here new CriterionTranslator implementations.
PortCriterion.class, new PortCriterionTranslator(),
EthCriterion.class, new EthCriterionTranslator(),
EthTypeCriterion.class, new EthTypeCriterionTranslator(),
IPCriterion.class, new IpCriterionTranslator()
);
private CriterionTranslatorHelper() {
// Hides constructor.
}
/**
* Translates a given criterion instance to a PiFieldMatch with the given id, match type, and bit-width.
*
* @param fieldId PI header field identifier
* @param criterion criterion
* @param matchType match type
* @param bitWidth size of the field match in bits
* @return a PI field match
* @throws PiFlowRuleTranslationException if the criterion cannot be translated (see exception message)
*/
static PiFieldMatch translateCriterion(Criterion criterion, PiHeaderFieldId fieldId, PiMatchType matchType,
int bitWidth)
throws PiFlowRuleTranslationException {
if (!TRANSLATORS.containsKey(criterion.getClass())) {
throw new PiFlowRuleTranslationException(format(
"Translation of criterion class %s is not implemented.",
criterion.getClass().getSimpleName()));
}
CriterionTranslator translator = TRANSLATORS.get(criterion.getClass());
try {
translator.init(criterion, bitWidth);
switch (matchType) {
case EXACT:
return new PiExactFieldMatch(fieldId, translator.exactMatch());
case TERNARY:
Pair<ImmutableByteSequence, ImmutableByteSequence> tp = translator.ternaryMatch();
return new PiTernaryFieldMatch(fieldId, tp.getLeft(), tp.getRight());
case LPM:
Pair<ImmutableByteSequence, Integer> lp = translator.lpmMatch();
return new PiLpmFieldMatch(fieldId, lp.getLeft(), lp.getRight());
default:
throw new PiFlowRuleTranslationException(format(
"Translation of criterion %s (%s class) to match type %s is not implemented.",
criterion.type().name(), criterion.getClass().getSimpleName(), matchType.name()));
}
} catch (ByteSequenceTrimException e) {
throw new PiFlowRuleTranslationException(format(
"Size mismatch for criterion %s: %s", criterion.type(), e.getMessage()));
} catch (CriterionTranslatorException e) {
throw new PiFlowRuleTranslationException(format(
"Unable to translate criterion %s: %s", criterion.type(), e.getMessage()));
}
}
}