blob: 0791f3ac081ccb0d96c0be18b36f6ac67fcd2a32 [file] [log] [blame]
Carmelo Cascone00a59962017-06-16 17:51:49 +09001/*
2 * Copyright 2017-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.net.pi.impl;
18
19import com.google.common.collect.ImmutableMap;
20import org.apache.commons.lang3.tuple.Pair;
21import org.onlab.util.ImmutableByteSequence;
22import org.onosproject.net.flow.criteria.Criterion;
23import org.onosproject.net.flow.criteria.EthCriterion;
24import org.onosproject.net.flow.criteria.EthTypeCriterion;
25import org.onosproject.net.flow.criteria.IPCriterion;
26import org.onosproject.net.flow.criteria.PortCriterion;
27import org.onosproject.net.pi.impl.CriterionTranslators.EthCriterionTranslator;
28import org.onosproject.net.pi.impl.CriterionTranslators.EthTypeCriterionTranslator;
29import org.onosproject.net.pi.impl.CriterionTranslators.IpCriterionTranslator;
30import org.onosproject.net.pi.impl.CriterionTranslators.PortCriterionTranslator;
31import org.onosproject.net.pi.model.PiMatchType;
32import org.onosproject.net.pi.runtime.PiExactFieldMatch;
33import org.onosproject.net.pi.runtime.PiFieldMatch;
34import org.onosproject.net.pi.runtime.PiHeaderFieldId;
35import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
36import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
37
38import java.util.Map;
39
40import static java.lang.String.format;
41import static org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException;
42import static org.onosproject.net.pi.impl.CriterionTranslator.CriterionTranslatorException;
43import static org.onosproject.net.pi.runtime.PiFlowRuleTranslationService.PiFlowRuleTranslationException;
44
45/**
46 * Helper class to translate criterion instances to PI field matches.
47 */
48final class CriterionTranslatorHelper {
49
50 private static final Map<Class<? extends Criterion>, CriterionTranslator> TRANSLATORS = ImmutableMap.of(
51 // Add here new CriterionTranslator implementations.
52 PortCriterion.class, new PortCriterionTranslator(),
53 EthCriterion.class, new EthCriterionTranslator(),
54 EthTypeCriterion.class, new EthTypeCriterionTranslator(),
55 IPCriterion.class, new IpCriterionTranslator()
56 );
57
58 private CriterionTranslatorHelper() {
59 // Hides constructor.
60 }
61
62 /**
63 * Translates a given criterion instance to a PiFieldMatch with the given id, match type, and bit-width.
64 *
65 * @param fieldId PI header field identifier
66 * @param criterion criterion
67 * @param matchType match type
68 * @param bitWidth size of the field match in bits
69 * @return a PI field match
70 * @throws PiFlowRuleTranslationException if the criterion cannot be translated (see exception message)
71 */
72 static PiFieldMatch translateCriterion(Criterion criterion, PiHeaderFieldId fieldId, PiMatchType matchType,
73 int bitWidth)
74 throws PiFlowRuleTranslationException {
75
76 if (!TRANSLATORS.containsKey(criterion.getClass())) {
77 throw new PiFlowRuleTranslationException(format(
78 "Translation of criterion class %s is not implemented.",
79 criterion.getClass().getSimpleName()));
80 }
81
82 CriterionTranslator translator = TRANSLATORS.get(criterion.getClass());
83
84 try {
85 translator.init(criterion, bitWidth);
86 switch (matchType) {
87 case EXACT:
88 return new PiExactFieldMatch(fieldId, translator.exactMatch());
89 case TERNARY:
90 Pair<ImmutableByteSequence, ImmutableByteSequence> tp = translator.ternaryMatch();
91 return new PiTernaryFieldMatch(fieldId, tp.getLeft(), tp.getRight());
92 case LPM:
93 Pair<ImmutableByteSequence, Integer> lp = translator.lpmMatch();
94 return new PiLpmFieldMatch(fieldId, lp.getLeft(), lp.getRight());
95 default:
96 throw new PiFlowRuleTranslationException(format(
97 "Translation of criterion %s (%s class) to match type %s is not implemented.",
98 criterion.type().name(), criterion.getClass().getSimpleName(), matchType.name()));
99 }
100 } catch (ByteSequenceTrimException e) {
101 throw new PiFlowRuleTranslationException(format(
102 "Size mismatch for criterion %s: %s", criterion.type(), e.getMessage()));
103 } catch (CriterionTranslatorException e) {
104 throw new PiFlowRuleTranslationException(format(
105 "Unable to translate criterion %s: %s", criterion.type(), e.getMessage()));
106 }
107 }
108}