blob: dfd8d85b63bfaba2f1101af4bb3ccdb206009829 [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 Tseng0b809722017-11-03 10:23:26 -070033import org.onosproject.net.flow.criteria.VlanIdCriterion;
34import org.onosproject.net.flowobjective.ForwardingObjective;
35import org.onosproject.net.flowobjective.ObjectiveError;
36import org.onosproject.net.pi.runtime.PiAction;
37import org.onosproject.net.pi.runtime.PiActionParam;
38import org.onosproject.pipelines.fabric.FabricConstants;
39import org.slf4j.Logger;
40
41import java.util.Set;
42
43import static com.google.common.base.Preconditions.checkNotNull;
44import static org.slf4j.LoggerFactory.getLogger;
45
46/**
47 * Handling forwarding objective for fabric pipeliner.
48 */
49public class FabricForwardingPipeliner {
50 private static final Logger log = getLogger(FabricForwardingPipeliner.class);
51
52 protected DeviceId deviceId;
53
54 public FabricForwardingPipeliner(DeviceId deviceId) {
55 this.deviceId = deviceId;
56 }
57
58 public PipelinerTranslationResult forward(ForwardingObjective forwardObjective) {
59 PipelinerTranslationResult.Builder resultBuilder = PipelinerTranslationResult.builder();
60 if (forwardObjective.flag() == ForwardingObjective.Flag.VERSATILE) {
61 processVersatileFwd(forwardObjective, resultBuilder);
62 } else {
63 processSpecificFwd(forwardObjective, resultBuilder);
64 }
65 return resultBuilder.build();
66 }
67
68 private void processVersatileFwd(ForwardingObjective fwd,
69 PipelinerTranslationResult.Builder resultBuilder) {
70 // program ACL table only
71 FlowRule flowRule = DefaultFlowRule.builder()
72 .withSelector(fwd.selector())
73 .withTreatment(fwd.treatment())
74 .forTable(FabricConstants.TBL_ACL_ID)
75 .withPriority(fwd.priority())
76 .forDevice(deviceId)
77 .makePermanent()
78 .fromApp(fwd.appId())
79 .build();
80 resultBuilder.addFlowRule(flowRule);
81 }
82
83 private void processSpecificFwd(ForwardingObjective fwd,
84 PipelinerTranslationResult.Builder resultBuilder) {
85 TrafficSelector selector = fwd.selector();
86 TrafficSelector meta = fwd.meta();
87
88 ImmutableSet.Builder<Criterion> criterionSetBuilder = ImmutableSet.builder();
89 criterionSetBuilder.addAll(selector.criteria());
90
91 if (meta != null) {
92 criterionSetBuilder.addAll(meta.criteria());
93 }
94
95 Set<Criterion> criteria = criterionSetBuilder.build();
96
97 VlanIdCriterion vlanIdCriterion = null;
98 EthCriterion ethDstCriterion = null;
Yi Tsengdbe05602017-11-17 18:02:43 -080099 IPCriterion ipDstCriterion = null;
Yi Tseng0b809722017-11-03 10:23:26 -0700100
101 for (Criterion criterion : criteria) {
102 switch (criterion.type()) {
103 case ETH_DST:
104 ethDstCriterion = (EthCriterion) criterion;
105 break;
106 case VLAN_VID:
107 vlanIdCriterion = (VlanIdCriterion) criterion;
108 break;
Yi Tsengdbe05602017-11-17 18:02:43 -0800109 case IPV4_DST:
110 ipDstCriterion = (IPCriterion) criterion;
111 break;
Yi Tseng0b809722017-11-03 10:23:26 -0700112 default:
113 log.warn("Unsupported criterion {}", criterion);
114 break;
115 }
116 }
117
118 ForwardingFunctionType forwardingFunctionType =
119 ForwardingFunctionType.getForwardingFunctionType(fwd);
120 switch (forwardingFunctionType) {
121 case L2_UNICAST:
122 processL2UnicastRule(vlanIdCriterion, ethDstCriterion, fwd, resultBuilder);
123 break;
124 case L2_BROADCAST:
125 processL2BroadcastRule(vlanIdCriterion, fwd, resultBuilder);
126 break;
127 case IPV4_UNICAST:
Yi Tsengdbe05602017-11-17 18:02:43 -0800128 processIpv4UnicastRule(ipDstCriterion, fwd, resultBuilder);
129 break;
Yi Tseng0b809722017-11-03 10:23:26 -0700130 case IPV4_MULTICAST:
131 case IPV6_UNICAST:
132 case IPV6_MULTICAST:
133 case MPLS:
134 default:
135 log.warn("Unsupported forwarding function type {}", criteria);
136 resultBuilder.setError(ObjectiveError.UNSUPPORTED);
137 break;
138 }
139 }
140
141 // L2 Unicast: learnt mac address + vlan
142 private void processL2UnicastRule(VlanIdCriterion vlanIdCriterion,
143 EthCriterion ethDstCriterion,
144 ForwardingObjective fwd,
145 PipelinerTranslationResult.Builder resultBuilder) {
146 checkNotNull(vlanIdCriterion, "VlanId criterion should not be null");
147 checkNotNull(ethDstCriterion, "EthDst criterion should not be null");
148
149 if (fwd.nextId() == null) {
150 log.warn("Forwarding objective for L2 unicast should contains next id");
151 resultBuilder.setError(ObjectiveError.BADPARAMS);
152 return;
153 }
154
155 VlanId vlanId = vlanIdCriterion.vlanId();
156 MacAddress ethDst = ethDstCriterion.mac();
157
158 TrafficSelector selector = DefaultTrafficSelector.builder()
159 .matchVlanId(vlanId)
160 .matchEthDst(ethDst)
161 .build();
162 TrafficTreatment treatment = buildSetNextIdTreatment(fwd.nextId());
163 FlowRule flowRule = DefaultFlowRule.builder()
164 .withSelector(selector)
165 .withTreatment(treatment)
166 .fromApp(fwd.appId())
167 .withPriority(fwd.priority())
168 .makePermanent()
169 .forDevice(deviceId)
170 .forTable(FabricConstants.TBL_BRIDGING_ID)
171 .build();
172
173 resultBuilder.addFlowRule(flowRule);
174 }
175
176 private void processL2BroadcastRule(VlanIdCriterion vlanIdCriterion,
177 ForwardingObjective fwd,
178 PipelinerTranslationResult.Builder resultBuilder) {
179 checkNotNull(vlanIdCriterion, "VlanId criterion should not be null");
180 if (fwd.nextId() == null) {
181 log.warn("Forwarding objective for L2 broadcast should contains next id");
182 resultBuilder.setError(ObjectiveError.BADPARAMS);
183 return;
184 }
185
186 VlanId vlanId = vlanIdCriterion.vlanId();
187
188 TrafficSelector selector = DefaultTrafficSelector.builder()
189 .matchVlanId(vlanId)
190 .build();
191 TrafficTreatment treatment = buildSetNextIdTreatment(fwd.nextId());
192 FlowRule flowRule = DefaultFlowRule.builder()
193 .withSelector(selector)
194 .withTreatment(treatment)
195 .fromApp(fwd.appId())
196 .withPriority(fwd.priority())
197 .makePermanent()
198 .forDevice(deviceId)
199 .forTable(FabricConstants.TBL_BRIDGING_ID)
200 .build();
201
202 resultBuilder.addFlowRule(flowRule);
203 }
204
Yi Tsengdbe05602017-11-17 18:02:43 -0800205 private void processIpv4UnicastRule(IPCriterion ipDstCriterion, ForwardingObjective fwd,
206 PipelinerTranslationResult.Builder resultBuilder) {
207 checkNotNull(ipDstCriterion, "IP dst criterion should not be null");
208 if (fwd.nextId() == null) {
209 log.warn("Forwarding objective for IPv4 unicast should contains next id");
210 resultBuilder.setError(ObjectiveError.BADPARAMS);
211 return;
212 }
213 TrafficSelector selector = DefaultTrafficSelector.builder()
214 .matchIPDst(ipDstCriterion.ip())
215 .build();
216
217 TrafficTreatment treatment = buildSetNextIdTreatment(fwd.nextId());
218 FlowRule flowRule = DefaultFlowRule.builder()
219 .withSelector(selector)
220 .withTreatment(treatment)
221 .fromApp(fwd.appId())
222 .withPriority(fwd.priority())
223 .makePermanent()
224 .forDevice(deviceId)
225 .forTable(FabricConstants.TBL_UNICAST_V4_ID)
226 .build();
227
228 resultBuilder.addFlowRule(flowRule);
229 }
230
Yi Tseng0b809722017-11-03 10:23:26 -0700231 private static TrafficTreatment buildSetNextIdTreatment(Integer nextId) {
232 PiActionParam nextIdParam = new PiActionParam(FabricConstants.ACT_PRM_NEXT_ID_ID,
233 ImmutableByteSequence.copyFrom(nextId.byteValue()));
234 PiAction nextIdAction = PiAction.builder()
235 .withId(FabricConstants.ACT_SET_NEXT_ID_ID)
236 .withParameter(nextIdParam)
237 .build();
238
239 return DefaultTrafficTreatment.builder()
240 .piTableAction(nextIdAction)
241 .build();
242 }
243
244}