use of org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException in project onos by opennetworkinglab.
the class CriterionTranslatorHelper method translateCriterion.
/**
* Translates a given criterion instance to a PiFieldMatch with the given id, match type, and bit-width.
*
* @param fieldId PI match field identifier
* @param criterion criterion
* @param matchType match type
* @param bitWidth size of the field match in bits
* @return a PI field match
* @throws PiTranslationException if the criterion cannot be translated (see exception message)
*/
static PiFieldMatch translateCriterion(Criterion criterion, PiMatchFieldId fieldId, PiMatchType matchType, int bitWidth) throws PiTranslationException {
if (!TRANSLATORS.containsKey(criterion.getClass())) {
throw new PiTranslationException(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 OPTIONAL:
return new PiOptionalFieldMatch(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 PiTranslationException(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 PiTranslationException(format("Size mismatch for criterion %s: %s", criterion.type(), e.getMessage()));
} catch (CriterionTranslatorException e) {
throw new PiTranslationException(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 IllegalStateException(e);
}
}
use of org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException in project onos by opennetworkinglab.
the class PiFlowRuleTranslatorImpl method checkPiAction.
private static PiTableAction checkPiAction(PiAction piAction, PiTableModel table) throws PiTranslationException {
// Table supports this action?
PiActionModel actionModel = table.action(piAction.id()).orElseThrow(() -> new PiTranslationException(format("Not such action '%s' for table '%s'", piAction.id(), table.id())));
// Is the number of runtime parameters correct?
if (actionModel.params().size() != piAction.parameters().size()) {
throw new PiTranslationException(format("Wrong number of runtime parameters for action '%s', expected %d but found %d", actionModel.id(), actionModel.params().size(), piAction.parameters().size()));
}
// Forge a new action instance with well-sized parameters.
// The same comment as in typeCheckFieldMatch() about duplicating field match instances applies here.
PiAction.Builder newActionBuilder = PiAction.builder().withId(piAction.id());
for (PiActionParam param : piAction.parameters()) {
PiActionParamModel paramModel = actionModel.param(param.id()).orElseThrow(() -> new PiTranslationException(format("Not such parameter '%s' for action '%s'", param.id(), actionModel)));
try {
newActionBuilder.withParameter(new PiActionParam(param.id(), paramModel.hasBitWidth() ? param.value().fit(paramModel.bitWidth()) : param.value()));
} catch (ByteSequenceTrimException e) {
throw new PiTranslationException(format("Size mismatch for parameter '%s' of action '%s': %s", param.id(), piAction.id(), e.getMessage()));
}
}
return newActionBuilder.build();
}
use of org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException in project onos by opennetworkinglab.
the class PiFlowRuleTranslatorImpl method typeCheckFieldMatch.
private static PiFieldMatch typeCheckFieldMatch(PiFieldMatch fieldMatch, PiMatchFieldModel fieldModel) throws PiTranslationException {
// Check parameter type and size
if (!fieldModel.matchType().equals(fieldMatch.type())) {
throw new PiTranslationException(format("Wrong match type for field '%s', expected %s, but found %s", fieldMatch.fieldId(), fieldModel.matchType().name(), fieldMatch.type().name()));
}
// Check if the arbitrary bit width is supported
if (!fieldModel.hasBitWidth() && !fieldModel.matchType().equals(PiMatchType.EXACT) && !fieldModel.matchType().equals(PiMatchType.OPTIONAL)) {
throw new PiTranslationException(format("Arbitrary bit width for field '%s' and match type %s is not supported", fieldMatch.fieldId(), fieldModel.matchType().name()));
}
int modelBitWidth = fieldModel.bitWidth();
try {
switch(fieldModel.matchType()) {
case EXACT:
PiExactFieldMatch exactField = (PiExactFieldMatch) fieldMatch;
return new PiExactFieldMatch(fieldMatch.fieldId(), fieldModel.hasBitWidth() ? exactField.value().fit(modelBitWidth) : exactField.value());
case TERNARY:
PiTernaryFieldMatch ternField = (PiTernaryFieldMatch) fieldMatch;
ImmutableByteSequence ternMask = ternField.mask().fit(modelBitWidth);
ImmutableByteSequence ternValue = ternField.value().fit(modelBitWidth).bitwiseAnd(ternMask);
return new PiTernaryFieldMatch(fieldMatch.fieldId(), ternValue, ternMask);
case LPM:
PiLpmFieldMatch lpmfield = (PiLpmFieldMatch) fieldMatch;
if (lpmfield.prefixLength() > modelBitWidth) {
throw new PiTranslationException(format("Invalid prefix length for LPM field '%s', found %d but field has bit-width %d", fieldMatch.fieldId(), lpmfield.prefixLength(), modelBitWidth));
}
ImmutableByteSequence lpmValue = lpmfield.value().fit(modelBitWidth);
ImmutableByteSequence lpmMask = prefixOnes(lpmValue.size(), lpmfield.prefixLength());
lpmValue = lpmValue.bitwiseAnd(lpmMask);
return new PiLpmFieldMatch(fieldMatch.fieldId(), lpmValue, lpmfield.prefixLength());
case RANGE:
return new PiRangeFieldMatch(fieldMatch.fieldId(), ((PiRangeFieldMatch) fieldMatch).lowValue().fit(modelBitWidth), ((PiRangeFieldMatch) fieldMatch).highValue().fit(modelBitWidth));
case OPTIONAL:
PiOptionalFieldMatch optionalField = (PiOptionalFieldMatch) fieldMatch;
return new PiOptionalFieldMatch(fieldMatch.fieldId(), fieldModel.hasBitWidth() ? optionalField.value().fit(modelBitWidth) : optionalField.value());
default:
// Should never be here.
throw new IllegalArgumentException("Unrecognized match type " + fieldModel.matchType().name());
}
} catch (ByteSequenceTrimException e) {
throw new PiTranslationException(format("Size mismatch for field %s: %s", fieldMatch.fieldId(), e.getMessage()));
}
}
Aggregations