blob: a6b213b60f9a1c5ac70bd14b0a2c58f30faba57e [file] [log] [blame]
Carmelo Cascone00a59962017-06-16 17:51:49 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Carmelo Cascone00a59962017-06-16 17:51:49 +09003 *
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 Cascone87892e22017-11-13 16:01:29 -080083import org.onosproject.net.pi.model.PiMatchFieldId;
Carmelo Cascone00a59962017-06-16 17:51:49 +090084import org.onosproject.net.pi.model.PiMatchType;
85import org.onosproject.net.pi.runtime.PiExactFieldMatch;
86import org.onosproject.net.pi.runtime.PiFieldMatch;
Carmelo Cascone00a59962017-06-16 17:51:49 +090087import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
Daniele Moroc6f2f7f2020-12-18 10:55:57 +010088import org.onosproject.net.pi.runtime.PiOptionalFieldMatch;
Carmelo Cascone00a59962017-06-16 17:51:49 +090089import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
Carmelo Cascone326ad2d2017-11-28 18:09:13 -080090import org.onosproject.net.pi.service.PiTranslationException;
Carmelo Cascone00a59962017-06-16 17:51:49 +090091
92import java.util.Map;
93
94import static java.lang.String.format;
95import static org.onlab.util.ImmutableByteSequence.ByteSequenceTrimException;
96import static org.onosproject.net.pi.impl.CriterionTranslator.CriterionTranslatorException;
Carmelo Cascone00a59962017-06-16 17:51:49 +090097
98/**
99 * Helper class to translate criterion instances to PI field matches.
100 */
101final class CriterionTranslatorHelper {
Carmelo Casconeabbd1ee2018-02-18 19:10:57 -0800102 private static final Map<Class<? extends Criterion>, Class<? extends CriterionTranslator>> TRANSLATORS =
Carmelo Cascone00a59962017-06-16 17:51:49 +0900103 // Add here new CriterionTranslator implementations.
Carmelo Casconeabbd1ee2018-02-18 19:10:57 -0800104 new ImmutableMap.Builder<Class<? extends Criterion>, Class<? extends CriterionTranslator>>()
105 .put(PortCriterion.class, PortCriterionTranslator.class)
106 .put(EthCriterion.class, EthCriterionTranslator.class)
107 .put(EthTypeCriterion.class, EthTypeCriterionTranslator.class)
108 .put(IPCriterion.class, IpCriterionTranslator.class)
109 .put(VlanIdCriterion.class, VlanIdCriterionTranslator.class)
110 .put(UdpPortCriterion.class, UdpPortCriterionTranslator.class)
111 .put(IPDscpCriterion.class, IPDscpCriterionTranslator.class)
112 .put(IPProtocolCriterion.class, IPProtocolCriterionTranslator.class)
113 .put(IPv6ExthdrFlagsCriterion.class, IPv6ExthdrFlagsCriterionTranslator.class)
114 .put(IPv6FlowLabelCriterion.class, IPv6FlowLabelCriterionTranslator.class)
115 .put(IPv6NDLinkLayerAddressCriterion.class, IPv6NDLinkLayerAddressCriterionTranslator.class)
116 .put(IPv6NDTargetAddressCriterion.class, IPv6NDTargetAddressCriterionTranslator.class)
117 .put(IcmpCodeCriterion.class, IcmpCodeCriterionTranslator.class)
118 .put(IcmpTypeCriterion.class, IcmpTypeCriterionTranslator.class)
119 .put(Icmpv6CodeCriterion.class, Icmpv6CodeCriterionTranslator.class)
120 .put(Icmpv6TypeCriterion.class, Icmpv6TypeCriterionTranslator.class)
121 .put(MplsBosCriterion.class, MplsBosCriterionTranslator.class)
122 .put(MplsCriterion.class, MplsCriterionTranslator.class)
123 .put(MplsTcCriterion.class, MplsTcCriterionTranslator.class)
124 .put(PbbIsidCriterion.class, PbbIsidCriterionTranslator.class)
125 .put(SctpPortCriterion.class, SctpPortCriterionTranslator.class)
126 .put(TcpFlagsCriterion.class, TcpFlagsCriterionTranslator.class)
127 .put(TcpPortCriterion.class, TcpPortCriterionTranslator.class)
128 .put(TunnelIdCriterion.class, TunnelIdCriterionTranslator.class)
129 .put(VlanPcpCriterion.class, VlanPcpCriterionTranslator.class)
130 .put(ArpHaCriterion.class, ArpHaCriterionTranslator.class)
131 .put(ArpOpCriterion.class, ArpOpCriterionTranslator.class)
132 .put(ArpPaCriterion.class, ArpPaCriterionTranslator.class)
133 .put(IPEcnCriterion.class, IPEcnCriterionTranslator.class)
134 .put(MetadataCriterion.class, MetadataCriterionTranslator.class)
zhiyong ke1667fbb2017-07-04 09:51:24 +0800135 .build();
Carmelo Cascone00a59962017-06-16 17:51:49 +0900136
137 private CriterionTranslatorHelper() {
138 // Hides constructor.
139 }
140
141 /**
142 * Translates a given criterion instance to a PiFieldMatch with the given id, match type, and bit-width.
143 *
Carmelo Cascone87892e22017-11-13 16:01:29 -0800144 * @param fieldId PI match field identifier
Carmelo Cascone00a59962017-06-16 17:51:49 +0900145 * @param criterion criterion
146 * @param matchType match type
147 * @param bitWidth size of the field match in bits
148 * @return a PI field match
Carmelo Cascone87b9b392017-10-02 18:33:20 +0200149 * @throws PiTranslationException if the criterion cannot be translated (see exception message)
Carmelo Cascone00a59962017-06-16 17:51:49 +0900150 */
Carmelo Cascone87892e22017-11-13 16:01:29 -0800151 static PiFieldMatch translateCriterion(Criterion criterion, PiMatchFieldId fieldId, PiMatchType matchType,
Carmelo Cascone00a59962017-06-16 17:51:49 +0900152 int bitWidth)
Carmelo Cascone87b9b392017-10-02 18:33:20 +0200153 throws PiTranslationException {
Carmelo Cascone00a59962017-06-16 17:51:49 +0900154
155 if (!TRANSLATORS.containsKey(criterion.getClass())) {
Carmelo Cascone87b9b392017-10-02 18:33:20 +0200156 throw new PiTranslationException(format(
Carmelo Cascone00a59962017-06-16 17:51:49 +0900157 "Translation of criterion class %s is not implemented.",
158 criterion.getClass().getSimpleName()));
159 }
160
Carmelo Cascone00a59962017-06-16 17:51:49 +0900161 try {
Carmelo Casconeabbd1ee2018-02-18 19:10:57 -0800162 final CriterionTranslator translator = TRANSLATORS.get(criterion.getClass()).newInstance();
Carmelo Cascone00a59962017-06-16 17:51:49 +0900163 translator.init(criterion, bitWidth);
164 switch (matchType) {
165 case EXACT:
166 return new PiExactFieldMatch(fieldId, translator.exactMatch());
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100167 case OPTIONAL:
168 return new PiOptionalFieldMatch(fieldId, translator.exactMatch());
Carmelo Cascone00a59962017-06-16 17:51:49 +0900169 case TERNARY:
Carmelo Casconeabbd1ee2018-02-18 19:10:57 -0800170 final Pair<ImmutableByteSequence, ImmutableByteSequence> tp = translator.ternaryMatch();
Carmelo Cascone00a59962017-06-16 17:51:49 +0900171 return new PiTernaryFieldMatch(fieldId, tp.getLeft(), tp.getRight());
172 case LPM:
Carmelo Casconeabbd1ee2018-02-18 19:10:57 -0800173 final Pair<ImmutableByteSequence, Integer> lp = translator.lpmMatch();
Carmelo Cascone00a59962017-06-16 17:51:49 +0900174 return new PiLpmFieldMatch(fieldId, lp.getLeft(), lp.getRight());
175 default:
Carmelo Cascone87b9b392017-10-02 18:33:20 +0200176 throw new PiTranslationException(format(
Carmelo Cascone00a59962017-06-16 17:51:49 +0900177 "Translation of criterion %s (%s class) to match type %s is not implemented.",
178 criterion.type().name(), criterion.getClass().getSimpleName(), matchType.name()));
179 }
180 } catch (ByteSequenceTrimException e) {
Carmelo Cascone87b9b392017-10-02 18:33:20 +0200181 throw new PiTranslationException(format(
Carmelo Cascone00a59962017-06-16 17:51:49 +0900182 "Size mismatch for criterion %s: %s", criterion.type(), e.getMessage()));
183 } catch (CriterionTranslatorException e) {
Carmelo Cascone87b9b392017-10-02 18:33:20 +0200184 throw new PiTranslationException(format(
Carmelo Cascone00a59962017-06-16 17:51:49 +0900185 "Unable to translate criterion %s: %s", criterion.type(), e.getMessage()));
Carmelo Casconeabbd1ee2018-02-18 19:10:57 -0800186 } catch (InstantiationException | IllegalAccessException e) {
187 // Was not able to instantiate the criterion translator.
Carmelo Cascone0e5632a2018-02-20 11:40:56 -0800188 throw new IllegalStateException(e);
Carmelo Cascone00a59962017-06-16 17:51:49 +0900189 }
190 }
191}