blob: bceefdd8bfc03210eed886ee619550954e98e71b [file] [log] [blame]
Yi Tseng0b809722017-11-03 10:23:26 -07001/*
2 * Copyright 2017-present Open Networking Foundation
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.pipelines.fabric.pipeliner;
18
19import com.google.common.collect.ImmutableSet;
20import org.onlab.packet.MacAddress;
21import org.onlab.packet.VlanId;
22import org.onlab.util.ImmutableByteSequence;
23import org.onosproject.net.DeviceId;
24import org.onosproject.net.flow.DefaultFlowRule;
25import org.onosproject.net.flow.DefaultTrafficSelector;
26import org.onosproject.net.flow.DefaultTrafficTreatment;
27import org.onosproject.net.flow.FlowRule;
28import org.onosproject.net.flow.TrafficSelector;
29import org.onosproject.net.flow.TrafficTreatment;
30import org.onosproject.net.flow.criteria.Criterion;
31import org.onosproject.net.flow.criteria.EthCriterion;
Yi Tsengdbe05602017-11-17 18:02:43 -080032import org.onosproject.net.flow.criteria.IPCriterion;
Yi Tseng1b154bd2017-11-20 17:48:19 -080033import org.onosproject.net.flow.criteria.MplsCriterion;
Yi Tseng0b809722017-11-03 10:23:26 -070034import org.onosproject.net.flow.criteria.VlanIdCriterion;
35import org.onosproject.net.flowobjective.ForwardingObjective;
36import org.onosproject.net.flowobjective.ObjectiveError;
37import org.onosproject.net.pi.runtime.PiAction;
38import org.onosproject.net.pi.runtime.PiActionParam;
39import org.onosproject.pipelines.fabric.FabricConstants;
40import org.slf4j.Logger;
41
42import java.util.Set;
43
44import static com.google.common.base.Preconditions.checkNotNull;
45import static org.slf4j.LoggerFactory.getLogger;
46
47/**
48 * Handling forwarding objective for fabric pipeliner.
49 */
50public class FabricForwardingPipeliner {
51 private static final Logger log = getLogger(FabricForwardingPipeliner.class);
52
53 protected DeviceId deviceId;
54
55 public FabricForwardingPipeliner(DeviceId deviceId) {
56 this.deviceId = deviceId;
57 }
58
59 public PipelinerTranslationResult forward(ForwardingObjective forwardObjective) {
60 PipelinerTranslationResult.Builder resultBuilder = PipelinerTranslationResult.builder();
61 if (forwardObjective.flag() == ForwardingObjective.Flag.VERSATILE) {
62 processVersatileFwd(forwardObjective, resultBuilder);
63 } else {
64 processSpecificFwd(forwardObjective, resultBuilder);
65 }
66 return resultBuilder.build();
67 }
68
69 private void processVersatileFwd(ForwardingObjective fwd,
70 PipelinerTranslationResult.Builder resultBuilder) {
71 // program ACL table only
72 FlowRule flowRule = DefaultFlowRule.builder()
73 .withSelector(fwd.selector())
74 .withTreatment(fwd.treatment())
75 .forTable(FabricConstants.TBL_ACL_ID)
76 .withPriority(fwd.priority())
77 .forDevice(deviceId)
78 .makePermanent()
79 .fromApp(fwd.appId())
80 .build();
81 resultBuilder.addFlowRule(flowRule);
82 }
83
84 private void processSpecificFwd(ForwardingObjective fwd,
85 PipelinerTranslationResult.Builder resultBuilder) {
86 TrafficSelector selector = fwd.selector();
87 TrafficSelector meta = fwd.meta();
88
89 ImmutableSet.Builder<Criterion> criterionSetBuilder = ImmutableSet.builder();
90 criterionSetBuilder.addAll(selector.criteria());
91
92 if (meta != null) {
93 criterionSetBuilder.addAll(meta.criteria());
94 }
95
96 Set<Criterion> criteria = criterionSetBuilder.build();
97
98 VlanIdCriterion vlanIdCriterion = null;
99 EthCriterion ethDstCriterion = null;
Yi Tsengdbe05602017-11-17 18:02:43 -0800100 IPCriterion ipDstCriterion = null;
Yi Tseng1b154bd2017-11-20 17:48:19 -0800101 MplsCriterion mplsCriterion = null;
Yi Tseng0b809722017-11-03 10:23:26 -0700102
103 for (Criterion criterion : criteria) {
104 switch (criterion.type()) {
105 case ETH_DST:
106 ethDstCriterion = (EthCriterion) criterion;
107 break;
108 case VLAN_VID:
109 vlanIdCriterion = (VlanIdCriterion) criterion;
110 break;
Yi Tsengdbe05602017-11-17 18:02:43 -0800111 case IPV4_DST:
112 ipDstCriterion = (IPCriterion) criterion;
113 break;
Yi Tseng1b154bd2017-11-20 17:48:19 -0800114 case MPLS_LABEL:
115 mplsCriterion = (MplsCriterion) criterion;
116 break;
117 case ETH_TYPE:
118 case MPLS_BOS:
119 // do nothing
120 break;
Yi Tseng0b809722017-11-03 10:23:26 -0700121 default:
122 log.warn("Unsupported criterion {}", criterion);
123 break;
124 }
125 }
126
127 ForwardingFunctionType forwardingFunctionType =
128 ForwardingFunctionType.getForwardingFunctionType(fwd);
129 switch (forwardingFunctionType) {
130 case L2_UNICAST:
131 processL2UnicastRule(vlanIdCriterion, ethDstCriterion, fwd, resultBuilder);
132 break;
133 case L2_BROADCAST:
134 processL2BroadcastRule(vlanIdCriterion, fwd, resultBuilder);
135 break;
136 case IPV4_UNICAST:
Yi Tsengdbe05602017-11-17 18:02:43 -0800137 processIpv4UnicastRule(ipDstCriterion, fwd, resultBuilder);
138 break;
Yi Tseng1b154bd2017-11-20 17:48:19 -0800139 case MPLS:
140 processMplsRule(mplsCriterion, fwd, resultBuilder);
141 break;
Yi Tseng0b809722017-11-03 10:23:26 -0700142 case IPV4_MULTICAST:
143 case IPV6_UNICAST:
144 case IPV6_MULTICAST:
Yi Tseng0b809722017-11-03 10:23:26 -0700145 default:
146 log.warn("Unsupported forwarding function type {}", criteria);
147 resultBuilder.setError(ObjectiveError.UNSUPPORTED);
148 break;
149 }
150 }
151
152 // L2 Unicast: learnt mac address + vlan
153 private void processL2UnicastRule(VlanIdCriterion vlanIdCriterion,
154 EthCriterion ethDstCriterion,
155 ForwardingObjective fwd,
156 PipelinerTranslationResult.Builder resultBuilder) {
157 checkNotNull(vlanIdCriterion, "VlanId criterion should not be null");
158 checkNotNull(ethDstCriterion, "EthDst criterion should not be null");
159
160 if (fwd.nextId() == null) {
161 log.warn("Forwarding objective for L2 unicast should contains next id");
162 resultBuilder.setError(ObjectiveError.BADPARAMS);
163 return;
164 }
165
166 VlanId vlanId = vlanIdCriterion.vlanId();
167 MacAddress ethDst = ethDstCriterion.mac();
168
169 TrafficSelector selector = DefaultTrafficSelector.builder()
170 .matchVlanId(vlanId)
171 .matchEthDst(ethDst)
172 .build();
173 TrafficTreatment treatment = buildSetNextIdTreatment(fwd.nextId());
174 FlowRule flowRule = DefaultFlowRule.builder()
175 .withSelector(selector)
176 .withTreatment(treatment)
177 .fromApp(fwd.appId())
178 .withPriority(fwd.priority())
179 .makePermanent()
180 .forDevice(deviceId)
181 .forTable(FabricConstants.TBL_BRIDGING_ID)
182 .build();
183
184 resultBuilder.addFlowRule(flowRule);
185 }
186
187 private void processL2BroadcastRule(VlanIdCriterion vlanIdCriterion,
188 ForwardingObjective fwd,
189 PipelinerTranslationResult.Builder resultBuilder) {
190 checkNotNull(vlanIdCriterion, "VlanId criterion should not be null");
191 if (fwd.nextId() == null) {
192 log.warn("Forwarding objective for L2 broadcast should contains next id");
193 resultBuilder.setError(ObjectiveError.BADPARAMS);
194 return;
195 }
196
197 VlanId vlanId = vlanIdCriterion.vlanId();
198
199 TrafficSelector selector = DefaultTrafficSelector.builder()
200 .matchVlanId(vlanId)
201 .build();
202 TrafficTreatment treatment = buildSetNextIdTreatment(fwd.nextId());
203 FlowRule flowRule = DefaultFlowRule.builder()
204 .withSelector(selector)
205 .withTreatment(treatment)
206 .fromApp(fwd.appId())
207 .withPriority(fwd.priority())
208 .makePermanent()
209 .forDevice(deviceId)
210 .forTable(FabricConstants.TBL_BRIDGING_ID)
211 .build();
212
213 resultBuilder.addFlowRule(flowRule);
214 }
215
Yi Tsengdbe05602017-11-17 18:02:43 -0800216 private void processIpv4UnicastRule(IPCriterion ipDstCriterion, ForwardingObjective fwd,
217 PipelinerTranslationResult.Builder resultBuilder) {
218 checkNotNull(ipDstCriterion, "IP dst criterion should not be null");
219 if (fwd.nextId() == null) {
220 log.warn("Forwarding objective for IPv4 unicast should contains next id");
221 resultBuilder.setError(ObjectiveError.BADPARAMS);
222 return;
223 }
224 TrafficSelector selector = DefaultTrafficSelector.builder()
225 .matchIPDst(ipDstCriterion.ip())
226 .build();
227
228 TrafficTreatment treatment = buildSetNextIdTreatment(fwd.nextId());
229 FlowRule flowRule = DefaultFlowRule.builder()
230 .withSelector(selector)
231 .withTreatment(treatment)
232 .fromApp(fwd.appId())
233 .withPriority(fwd.priority())
234 .makePermanent()
235 .forDevice(deviceId)
236 .forTable(FabricConstants.TBL_UNICAST_V4_ID)
237 .build();
238
239 resultBuilder.addFlowRule(flowRule);
240 }
241
Yi Tseng1b154bd2017-11-20 17:48:19 -0800242 private void processMplsRule(MplsCriterion mplsCriterion, ForwardingObjective fwd,
243 PipelinerTranslationResult.Builder resultBuilder) {
244 checkNotNull(mplsCriterion, "Mpls criterion should not be null");
245 if (fwd.nextId() == null) {
246 log.warn("Forwarding objective for MPLS should contains next id");
247 resultBuilder.setError(ObjectiveError.BADPARAMS);
248 return;
249 }
250 TrafficSelector selector = DefaultTrafficSelector.builder()
251 .add(mplsCriterion)
252 .build();
253
254 PiActionParam nextIdParam = new PiActionParam(FabricConstants.ACT_PRM_NEXT_ID_ID,
255 ImmutableByteSequence.copyFrom(fwd.nextId().byteValue()));
256 PiAction nextIdAction = PiAction.builder()
257 .withId(FabricConstants.ACT_POP_MPLS_AND_NEXT_ID)
258 .withParameter(nextIdParam)
259 .build();
260 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
261 .piTableAction(nextIdAction)
262 .build();
263
264 FlowRule flowRule = DefaultFlowRule.builder()
265 .withSelector(selector)
266 .withTreatment(treatment)
267 .fromApp(fwd.appId())
268 .withPriority(fwd.priority())
269 .makePermanent()
270 .forDevice(deviceId)
271 .forTable(FabricConstants.TBL_MPLS_ID)
272 .build();
273
274 resultBuilder.addFlowRule(flowRule);
275 }
276
Yi Tseng0b809722017-11-03 10:23:26 -0700277 private static TrafficTreatment buildSetNextIdTreatment(Integer nextId) {
278 PiActionParam nextIdParam = new PiActionParam(FabricConstants.ACT_PRM_NEXT_ID_ID,
279 ImmutableByteSequence.copyFrom(nextId.byteValue()));
280 PiAction nextIdAction = PiAction.builder()
281 .withId(FabricConstants.ACT_SET_NEXT_ID_ID)
282 .withParameter(nextIdParam)
283 .build();
284
285 return DefaultTrafficTreatment.builder()
286 .piTableAction(nextIdAction)
287 .build();
288 }
Yi Tseng0b809722017-11-03 10:23:26 -0700289}