blob: 3ef7f83f22897ff813f31f5b2af6685ab679c1c2 [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;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040022import org.onosproject.net.flow.criteria.ArpHaCriterion;
23import org.onosproject.net.flow.criteria.ArpOpCriterion;
24import org.onosproject.net.flow.criteria.ArpPaCriterion;
Carmelo Cascone00a59962017-06-16 17:51:49 +090025import org.onosproject.net.flow.criteria.Criterion;
26import org.onosproject.net.flow.criteria.EthCriterion;
27import org.onosproject.net.flow.criteria.EthTypeCriterion;
28import org.onosproject.net.flow.criteria.IPCriterion;
zhiyong kef2e6a482017-07-10 20:32:20 +080029import org.onosproject.net.flow.criteria.IPDscpCriterion;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040030import org.onosproject.net.flow.criteria.IPEcnCriterion;
zhiyong kef2e6a482017-07-10 20:32:20 +080031import org.onosproject.net.flow.criteria.IPProtocolCriterion;
32import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
33import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
34import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
35import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
36import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
37import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
38import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
39import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040040import org.onosproject.net.flow.criteria.MetadataCriterion;
zhiyong kef2e6a482017-07-10 20:32:20 +080041import org.onosproject.net.flow.criteria.MplsBosCriterion;
42import org.onosproject.net.flow.criteria.MplsCriterion;
43import org.onosproject.net.flow.criteria.MplsTcCriterion;
zhiyong kef2e6a482017-07-10 20:32:20 +080044import org.onosproject.net.flow.criteria.PbbIsidCriterion;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040045import org.onosproject.net.flow.criteria.PortCriterion;
zhiyong kef2e6a482017-07-10 20:32:20 +080046import org.onosproject.net.flow.criteria.SctpPortCriterion;
47import org.onosproject.net.flow.criteria.TcpFlagsCriterion;
48import org.onosproject.net.flow.criteria.TcpPortCriterion;
49import org.onosproject.net.flow.criteria.TunnelIdCriterion;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040050import org.onosproject.net.flow.criteria.UdpPortCriterion;
51import org.onosproject.net.flow.criteria.VlanIdCriterion;
zhiyong kef2e6a482017-07-10 20:32:20 +080052import org.onosproject.net.flow.criteria.VlanPcpCriterion;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040053import org.onosproject.net.pi.impl.CriterionTranslators.ArpHaCriterionTranslator;
54import org.onosproject.net.pi.impl.CriterionTranslators.ArpOpCriterionTranslator;
55import org.onosproject.net.pi.impl.CriterionTranslators.ArpPaCriterionTranslator;
Carmelo Cascone00a59962017-06-16 17:51:49 +090056import org.onosproject.net.pi.impl.CriterionTranslators.EthCriterionTranslator;
57import org.onosproject.net.pi.impl.CriterionTranslators.EthTypeCriterionTranslator;
zhiyong kef2e6a482017-07-10 20:32:20 +080058import org.onosproject.net.pi.impl.CriterionTranslators.IPDscpCriterionTranslator;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040059import org.onosproject.net.pi.impl.CriterionTranslators.IPEcnCriterionTranslator;
zhiyong kef2e6a482017-07-10 20:32:20 +080060import org.onosproject.net.pi.impl.CriterionTranslators.IPProtocolCriterionTranslator;
61import org.onosproject.net.pi.impl.CriterionTranslators.IPv6ExthdrFlagsCriterionTranslator;
62import org.onosproject.net.pi.impl.CriterionTranslators.IPv6FlowLabelCriterionTranslator;
63import org.onosproject.net.pi.impl.CriterionTranslators.IPv6NDLinkLayerAddressCriterionTranslator;
64import org.onosproject.net.pi.impl.CriterionTranslators.IPv6NDTargetAddressCriterionTranslator;
65import org.onosproject.net.pi.impl.CriterionTranslators.IcmpCodeCriterionTranslator;
66import org.onosproject.net.pi.impl.CriterionTranslators.IcmpTypeCriterionTranslator;
67import org.onosproject.net.pi.impl.CriterionTranslators.Icmpv6CodeCriterionTranslator;
68import org.onosproject.net.pi.impl.CriterionTranslators.Icmpv6TypeCriterionTranslator;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040069import org.onosproject.net.pi.impl.CriterionTranslators.IpCriterionTranslator;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040070import org.onosproject.net.pi.impl.CriterionTranslators.MetadataCriterionTranslator;
zhiyong kef2e6a482017-07-10 20:32:20 +080071import org.onosproject.net.pi.impl.CriterionTranslators.MplsBosCriterionTranslator;
72import org.onosproject.net.pi.impl.CriterionTranslators.MplsCriterionTranslator;
73import org.onosproject.net.pi.impl.CriterionTranslators.MplsTcCriterionTranslator;
zhiyong kef2e6a482017-07-10 20:32:20 +080074import org.onosproject.net.pi.impl.CriterionTranslators.PbbIsidCriterionTranslator;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040075import org.onosproject.net.pi.impl.CriterionTranslators.PortCriterionTranslator;
zhiyong kef2e6a482017-07-10 20:32:20 +080076import org.onosproject.net.pi.impl.CriterionTranslators.SctpPortCriterionTranslator;
77import org.onosproject.net.pi.impl.CriterionTranslators.TcpFlagsCriterionTranslator;
78import org.onosproject.net.pi.impl.CriterionTranslators.TcpPortCriterionTranslator;
79import org.onosproject.net.pi.impl.CriterionTranslators.TunnelIdCriterionTranslator;
Carmelo Cascone3bf51572017-07-13 17:16:42 -040080import org.onosproject.net.pi.impl.CriterionTranslators.UdpPortCriterionTranslator;
81import org.onosproject.net.pi.impl.CriterionTranslators.VlanIdCriterionTranslator;
zhiyong kef2e6a482017-07-10 20:32:20 +080082import org.onosproject.net.pi.impl.CriterionTranslators.VlanPcpCriterionTranslator;
Carmelo Cascone00a59962017-06-16 17:51:49 +090083import org.onosproject.net.pi.model.PiMatchType;
84import org.onosproject.net.pi.runtime.PiExactFieldMatch;
85import org.onosproject.net.pi.runtime.PiFieldMatch;
86import org.onosproject.net.pi.runtime.PiHeaderFieldId;
87import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
88import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
89
90import java.util.Map;
91
92import static java.lang.String.format;
93import static org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException;
94import static org.onosproject.net.pi.impl.CriterionTranslator.CriterionTranslatorException;
95import static org.onosproject.net.pi.runtime.PiFlowRuleTranslationService.PiFlowRuleTranslationException;
96
97/**
98 * Helper class to translate criterion instances to PI field matches.
99 */
100final class CriterionTranslatorHelper {
zhiyong ke1667fbb2017-07-04 09:51:24 +0800101 private static final Map<Class<? extends Criterion>, CriterionTranslator> TRANSLATORS =
Carmelo Cascone00a59962017-06-16 17:51:49 +0900102 // Add here new CriterionTranslator implementations.
zhiyong ke1667fbb2017-07-04 09:51:24 +0800103 new ImmutableMap.Builder<Class<? extends Criterion>, CriterionTranslator>()
104 .put(PortCriterion.class, new PortCriterionTranslator())
105 .put(EthCriterion.class, new EthCriterionTranslator())
106 .put(EthTypeCriterion.class, new EthTypeCriterionTranslator())
107 .put(IPCriterion.class, new IpCriterionTranslator())
zhiyong kef2e6a482017-07-10 20:32:20 +0800108 .put(VlanIdCriterion.class, new VlanIdCriterionTranslator())
109 .put(UdpPortCriterion.class, new UdpPortCriterionTranslator())
zhiyong kef2e6a482017-07-10 20:32:20 +0800110 .put(IPDscpCriterion.class, new IPDscpCriterionTranslator())
111 .put(IPProtocolCriterion.class, new IPProtocolCriterionTranslator())
112 .put(IPv6ExthdrFlagsCriterion.class, new IPv6ExthdrFlagsCriterionTranslator())
113 .put(IPv6FlowLabelCriterion.class, new IPv6FlowLabelCriterionTranslator())
114 .put(IPv6NDLinkLayerAddressCriterion.class, new IPv6NDLinkLayerAddressCriterionTranslator())
115 .put(IPv6NDTargetAddressCriterion.class, new IPv6NDTargetAddressCriterionTranslator())
116 .put(IcmpCodeCriterion.class, new IcmpCodeCriterionTranslator())
117 .put(IcmpTypeCriterion.class, new IcmpTypeCriterionTranslator())
118 .put(Icmpv6CodeCriterion.class, new Icmpv6CodeCriterionTranslator())
119 .put(Icmpv6TypeCriterion.class, new Icmpv6TypeCriterionTranslator())
zhiyong kef2e6a482017-07-10 20:32:20 +0800120 .put(MplsBosCriterion.class, new MplsBosCriterionTranslator())
121 .put(MplsCriterion.class, new MplsCriterionTranslator())
122 .put(MplsTcCriterion.class, new MplsTcCriterionTranslator())
zhiyong kef2e6a482017-07-10 20:32:20 +0800123 .put(PbbIsidCriterion.class, new PbbIsidCriterionTranslator())
zhiyong kef2e6a482017-07-10 20:32:20 +0800124 .put(SctpPortCriterion.class, new SctpPortCriterionTranslator())
125 .put(TcpFlagsCriterion.class, new TcpFlagsCriterionTranslator())
126 .put(TcpPortCriterion.class, new TcpPortCriterionTranslator())
127 .put(TunnelIdCriterion.class, new TunnelIdCriterionTranslator())
128 .put(VlanPcpCriterion.class, new VlanPcpCriterionTranslator())
129 .put(ArpHaCriterion.class, new ArpHaCriterionTranslator())
130 .put(ArpOpCriterion.class, new ArpOpCriterionTranslator())
131 .put(ArpPaCriterion.class, new ArpPaCriterionTranslator())
zhiyong ke897fd2d2017-07-12 11:41:38 +0800132 .put(IPEcnCriterion.class, new IPEcnCriterionTranslator())
133 .put(MetadataCriterion.class, new MetadataCriterionTranslator())
zhiyong ke1667fbb2017-07-04 09:51:24 +0800134 .build();
Carmelo Cascone00a59962017-06-16 17:51:49 +0900135
136 private CriterionTranslatorHelper() {
137 // Hides constructor.
138 }
139
140 /**
141 * Translates a given criterion instance to a PiFieldMatch with the given id, match type, and bit-width.
142 *
143 * @param fieldId PI header field identifier
144 * @param criterion criterion
145 * @param matchType match type
146 * @param bitWidth size of the field match in bits
147 * @return a PI field match
148 * @throws PiFlowRuleTranslationException if the criterion cannot be translated (see exception message)
149 */
150 static PiFieldMatch translateCriterion(Criterion criterion, PiHeaderFieldId fieldId, PiMatchType matchType,
151 int bitWidth)
152 throws PiFlowRuleTranslationException {
153
154 if (!TRANSLATORS.containsKey(criterion.getClass())) {
155 throw new PiFlowRuleTranslationException(format(
156 "Translation of criterion class %s is not implemented.",
157 criterion.getClass().getSimpleName()));
158 }
159
160 CriterionTranslator translator = TRANSLATORS.get(criterion.getClass());
161
162 try {
163 translator.init(criterion, bitWidth);
164 switch (matchType) {
165 case EXACT:
166 return new PiExactFieldMatch(fieldId, translator.exactMatch());
167 case TERNARY:
168 Pair<ImmutableByteSequence, ImmutableByteSequence> tp = translator.ternaryMatch();
169 return new PiTernaryFieldMatch(fieldId, tp.getLeft(), tp.getRight());
170 case LPM:
171 Pair<ImmutableByteSequence, Integer> lp = translator.lpmMatch();
172 return new PiLpmFieldMatch(fieldId, lp.getLeft(), lp.getRight());
173 default:
174 throw new PiFlowRuleTranslationException(format(
175 "Translation of criterion %s (%s class) to match type %s is not implemented.",
176 criterion.type().name(), criterion.getClass().getSimpleName(), matchType.name()));
177 }
178 } catch (ByteSequenceTrimException e) {
179 throw new PiFlowRuleTranslationException(format(
180 "Size mismatch for criterion %s: %s", criterion.type(), e.getMessage()));
181 } catch (CriterionTranslatorException e) {
182 throw new PiFlowRuleTranslationException(format(
183 "Unable to translate criterion %s: %s", criterion.type(), e.getMessage()));
184 }
185 }
186}