blob: f39e3e12c5f76d761052baae18eca16508416677 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* 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.ArpHaCriterion;
import org.onosproject.net.flow.criteria.ArpOpCriterion;
import org.onosproject.net.flow.criteria.ArpPaCriterion;
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.IPDscpCriterion;
import org.onosproject.net.flow.criteria.IPEcnCriterion;
import org.onosproject.net.flow.criteria.IPProtocolCriterion;
import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
import org.onosproject.net.flow.criteria.MetadataCriterion;
import org.onosproject.net.flow.criteria.MplsBosCriterion;
import org.onosproject.net.flow.criteria.MplsCriterion;
import org.onosproject.net.flow.criteria.MplsTcCriterion;
import org.onosproject.net.flow.criteria.PbbIsidCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.SctpPortCriterion;
import org.onosproject.net.flow.criteria.TcpFlagsCriterion;
import org.onosproject.net.flow.criteria.TcpPortCriterion;
import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
import org.onosproject.net.pi.impl.CriterionTranslators.ArpHaCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.ArpOpCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.ArpPaCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.EthCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.EthTypeCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IPDscpCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IPEcnCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IPProtocolCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IPv6ExthdrFlagsCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IPv6FlowLabelCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IPv6NDLinkLayerAddressCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IPv6NDTargetAddressCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IcmpCodeCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IcmpTypeCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.Icmpv6CodeCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.Icmpv6TypeCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.IpCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.MetadataCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.MplsBosCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.MplsCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.MplsTcCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.PbbIsidCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.PortCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.SctpPortCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.TcpFlagsCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.TcpPortCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.TunnelIdCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.UdpPortCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.VlanIdCriterionTranslator;
import org.onosproject.net.pi.impl.CriterionTranslators.VlanPcpCriterionTranslator;
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>, Class<? extends CriterionTranslator>> TRANSLATORS =
// Add here new CriterionTranslator implementations.
new ImmutableMap.Builder<Class<? extends Criterion>, Class<? extends CriterionTranslator>>()
.put(PortCriterion.class, PortCriterionTranslator.class)
.put(EthCriterion.class, EthCriterionTranslator.class)
.put(EthTypeCriterion.class, EthTypeCriterionTranslator.class)
.put(IPCriterion.class, IpCriterionTranslator.class)
.put(VlanIdCriterion.class, VlanIdCriterionTranslator.class)
.put(UdpPortCriterion.class, UdpPortCriterionTranslator.class)
.put(IPDscpCriterion.class, IPDscpCriterionTranslator.class)
.put(IPProtocolCriterion.class, IPProtocolCriterionTranslator.class)
.put(IPv6ExthdrFlagsCriterion.class, IPv6ExthdrFlagsCriterionTranslator.class)
.put(IPv6FlowLabelCriterion.class, IPv6FlowLabelCriterionTranslator.class)
.put(IPv6NDLinkLayerAddressCriterion.class, IPv6NDLinkLayerAddressCriterionTranslator.class)
.put(IPv6NDTargetAddressCriterion.class, IPv6NDTargetAddressCriterionTranslator.class)
.put(IcmpCodeCriterion.class, IcmpCodeCriterionTranslator.class)
.put(IcmpTypeCriterion.class, IcmpTypeCriterionTranslator.class)
.put(Icmpv6CodeCriterion.class, Icmpv6CodeCriterionTranslator.class)
.put(Icmpv6TypeCriterion.class, Icmpv6TypeCriterionTranslator.class)
.put(MplsBosCriterion.class, MplsBosCriterionTranslator.class)
.put(MplsCriterion.class, MplsCriterionTranslator.class)
.put(MplsTcCriterion.class, MplsTcCriterionTranslator.class)
.put(PbbIsidCriterion.class, PbbIsidCriterionTranslator.class)
.put(SctpPortCriterion.class, SctpPortCriterionTranslator.class)
.put(TcpFlagsCriterion.class, TcpFlagsCriterionTranslator.class)
.put(TcpPortCriterion.class, TcpPortCriterionTranslator.class)
.put(TunnelIdCriterion.class, TunnelIdCriterionTranslator.class)
.put(VlanPcpCriterion.class, VlanPcpCriterionTranslator.class)
.put(ArpHaCriterion.class, ArpHaCriterionTranslator.class)
.put(ArpOpCriterion.class, ArpOpCriterionTranslator.class)
.put(ArpPaCriterion.class, ArpPaCriterionTranslator.class)
.put(IPEcnCriterion.class, IPEcnCriterionTranslator.class)
.put(MetadataCriterion.class, MetadataCriterionTranslator.class)
.build();
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()));
}
try {
final CriterionTranslator translator = TRANSLATORS.get(criterion.getClass()).newInstance();
translator.init(criterion, bitWidth);
switch (matchType) {
case EXACT:
return new PiExactFieldMatch(fieldId, translator.exactMatch());
case TERNARY:
final Pair<ImmutableByteSequence, ImmutableByteSequence> tp = translator.ternaryMatch();
return new PiTernaryFieldMatch(fieldId, tp.getLeft(), tp.getRight());
case LPM:
final 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()));
} catch (InstantiationException | IllegalAccessException e) {
// Was not able to instantiate the criterion translator.
throw new RuntimeException(e);
}
}
}