blob: 67cbaa7f87fc021d31005f26f828eccfd1154af3 [file] [log] [blame]
sangho5afd02a2015-02-03 20:07:35 -08001/*
2 * Copyright 2015 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 */
16package org.onosproject.provider.of.group.impl;
17
18import com.google.common.collect.Lists;
Michele Santuari4b6019e2014-12-19 11:31:45 +010019
Ray Milkey84d5a292016-02-22 14:04:01 -080020import org.onlab.packet.EthType;
sangho5afd02a2015-02-03 20:07:35 -080021import org.onlab.packet.Ip4Address;
22import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010023import org.onlab.packet.MplsLabel;
sangho5afd02a2015-02-03 20:07:35 -080024import org.onlab.packet.VlanId;
25import org.onosproject.core.DefaultGroupId;
26import org.onosproject.core.GroupId;
Hyunsun Moona834c182015-12-16 03:01:56 -080027import org.onosproject.net.DeviceId;
Sho SHIMIZU9553bb82015-06-30 16:02:45 -070028import org.onosproject.net.Lambda;
sangho5afd02a2015-02-03 20:07:35 -080029import org.onosproject.net.PortNumber;
Hyunsun Moona834c182015-12-16 03:01:56 -080030import org.onosproject.net.driver.DefaultDriverData;
31import org.onosproject.net.driver.DefaultDriverHandler;
32import org.onosproject.net.driver.Driver;
33import org.onosproject.net.driver.DriverHandler;
34import org.onosproject.net.driver.DriverService;
sangho5afd02a2015-02-03 20:07:35 -080035import org.onosproject.net.flow.DefaultTrafficTreatment;
36import org.onosproject.net.flow.TrafficTreatment;
Sho SHIMIZU9553bb82015-06-30 16:02:45 -070037import org.onosproject.net.flow.instructions.Instructions;
sangho5afd02a2015-02-03 20:07:35 -080038import org.onosproject.net.group.DefaultGroupBucket;
39import org.onosproject.net.group.GroupBucket;
40import org.onosproject.net.group.GroupBuckets;
Hyunsun Moona834c182015-12-16 03:01:56 -080041import org.onosproject.openflow.controller.Dpid;
42import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
sangho5afd02a2015-02-03 20:07:35 -080043import org.projectfloodlight.openflow.protocol.OFBucket;
44import org.projectfloodlight.openflow.protocol.OFGroupType;
45import org.projectfloodlight.openflow.protocol.action.OFAction;
46import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
47import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlIn;
48import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlOut;
49import org.projectfloodlight.openflow.protocol.action.OFActionDecMplsTtl;
50import org.projectfloodlight.openflow.protocol.action.OFActionDecNwTtl;
51import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
Saurav Das88329902015-05-27 23:22:32 -070052import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
sangho5afd02a2015-02-03 20:07:35 -080053import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
54import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls;
55import org.projectfloodlight.openflow.protocol.action.OFActionPushMpls;
56import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
57import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
58import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
59import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
60import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
61import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
62import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
63import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
64import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
65import org.projectfloodlight.openflow.types.IPv4Address;
66import org.projectfloodlight.openflow.types.OFVlanVidMatch;
67import org.projectfloodlight.openflow.types.U32;
Hyunsun Moona834c182015-12-16 03:01:56 -080068import org.projectfloodlight.openflow.types.U64;
Saurav Das73a7dd42015-08-19 22:20:31 -070069import org.projectfloodlight.openflow.types.U8;
sangho5afd02a2015-02-03 20:07:35 -080070import org.projectfloodlight.openflow.types.VlanPcp;
71import org.slf4j.Logger;
72
73import java.util.List;
74
75import static org.slf4j.LoggerFactory.getLogger;
76
77/*
78 * Builder for GroupBucketEntry.
79 */
80public class GroupBucketEntryBuilder {
81
Hyunsun Moona834c182015-12-16 03:01:56 -080082 private Dpid dpid;
sangho5afd02a2015-02-03 20:07:35 -080083 private List<OFBucket> ofBuckets;
84 private OFGroupType type;
Hyunsun Moona834c182015-12-16 03:01:56 -080085 private DriverService driverService;
sangho5afd02a2015-02-03 20:07:35 -080086
87 private final Logger log = getLogger(getClass());
88
Hyunsun Moona834c182015-12-16 03:01:56 -080089
sangho5afd02a2015-02-03 20:07:35 -080090 /**
91 * Creates a builder.
92 *
Hyunsun Moona834c182015-12-16 03:01:56 -080093 * @param dpid dpid
sangho5afd02a2015-02-03 20:07:35 -080094 * @param ofBuckets list of OFBucket
95 * @param type Group type
Hyunsun Moona834c182015-12-16 03:01:56 -080096 * @param driverService driver service
sangho5afd02a2015-02-03 20:07:35 -080097 */
Hyunsun Moona834c182015-12-16 03:01:56 -080098 public GroupBucketEntryBuilder(Dpid dpid, List<OFBucket> ofBuckets, OFGroupType type,
99 DriverService driverService) {
100 this.dpid = dpid;
sangho5afd02a2015-02-03 20:07:35 -0800101 this.ofBuckets = ofBuckets;
102 this.type = type;
Hyunsun Moona834c182015-12-16 03:01:56 -0800103 this.driverService = driverService;
sangho5afd02a2015-02-03 20:07:35 -0800104 }
105
106 /**
107 * Builds a GroupBuckets.
108 *
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700109 * @return GroupBuckets object, a list of GroupBuckets
sangho5afd02a2015-02-03 20:07:35 -0800110 */
111 public GroupBuckets build() {
112 List<GroupBucket> bucketList = Lists.newArrayList();
113
114 for (OFBucket bucket: ofBuckets) {
115 TrafficTreatment treatment = buildTreatment(bucket.getActions());
116 // TODO: Use GroupBucketEntry
117 GroupBucket groupBucket = null;
118 switch (type) {
119 case INDIRECT:
120 groupBucket =
121 DefaultGroupBucket.createIndirectGroupBucket(treatment);
122 break;
123 case SELECT:
124 groupBucket =
125 DefaultGroupBucket.createSelectGroupBucket(treatment);
126 break;
127 case FF:
128 PortNumber port =
129 PortNumber.portNumber(bucket.getWatchPort().getPortNumber());
130 GroupId groupId =
131 new DefaultGroupId(bucket.getWatchGroup().getGroupNumber());
132 groupBucket =
133 DefaultGroupBucket.createFailoverGroupBucket(treatment,
134 port, groupId);
135 break;
Charles Chanc42e84e2015-10-20 16:24:19 -0700136 case ALL:
137 groupBucket =
138 DefaultGroupBucket.createAllGroupBucket(treatment);
139 break;
sangho5afd02a2015-02-03 20:07:35 -0800140 default:
141 log.error("Unsupported Group type : {}", type);
142 }
143 if (groupBucket != null) {
144 bucketList.add(groupBucket);
145 }
146 }
147 return new GroupBuckets(bucketList);
148 }
149
150
151 private TrafficTreatment buildTreatment(List<OFAction> actions) {
152 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
153 // If this is a drop rule
154 if (actions.size() == 0) {
155 builder.drop();
156 return builder.build();
157 }
158 for (OFAction act : actions) {
159 switch (act.getType()) {
160 case OUTPUT:
161 OFActionOutput out = (OFActionOutput) act;
162 builder.setOutput(
163 PortNumber.portNumber(out.getPort().getPortNumber()));
164 break;
165 case SET_VLAN_VID:
166 OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
167 builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan()));
168 break;
169 case SET_VLAN_PCP:
170 OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
171 builder.setVlanPcp(pcp.getVlanPcp().getValue());
172 break;
Jonathan Harte106e4b2015-03-09 16:44:56 -0700173 case POP_VLAN:
174 builder.popVlan();
175 break;
176 case PUSH_VLAN:
177 builder.pushVlan();
178 break;
sangho5afd02a2015-02-03 20:07:35 -0800179 case SET_DL_DST:
180 OFActionSetDlDst dldst = (OFActionSetDlDst) act;
181 builder.setEthDst(
182 MacAddress.valueOf(dldst.getDlAddr().getLong()));
183 break;
184 case SET_DL_SRC:
185 OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
186 builder.setEthSrc(
187 MacAddress.valueOf(dlsrc.getDlAddr().getLong()));
188
189 break;
190 case SET_NW_DST:
191 OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
192 IPv4Address di = nwdst.getNwAddr();
193 builder.setIpDst(Ip4Address.valueOf(di.getInt()));
194 break;
195 case SET_NW_SRC:
196 OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
197 IPv4Address si = nwsrc.getNwAddr();
198 builder.setIpSrc(Ip4Address.valueOf(si.getInt()));
199 break;
200 case EXPERIMENTER:
201 OFActionExperimenter exp = (OFActionExperimenter) act;
202 if (exp.getExperimenter() == 0x80005A06 ||
203 exp.getExperimenter() == 0x748771) {
204 OFActionCircuit ct = (OFActionCircuit) exp;
Sho SHIMIZU9553bb82015-06-30 16:02:45 -0700205 short lambda = ((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber();
206 builder.add(Instructions.modL0Lambda(Lambda.indexedLambda(lambda)));
sangho5afd02a2015-02-03 20:07:35 -0800207 } else {
208 log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter());
209 }
210 break;
211 case SET_FIELD:
212 OFActionSetField setField = (OFActionSetField) act;
Hyunsun Moona834c182015-12-16 03:01:56 -0800213 handleSetField(builder, setField);
sangho5afd02a2015-02-03 20:07:35 -0800214 break;
215 case POP_MPLS:
216 OFActionPopMpls popMpls = (OFActionPopMpls) act;
Ray Milkey84d5a292016-02-22 14:04:01 -0800217 builder.popMpls(new EthType(popMpls.getEthertype().getValue()));
sangho5afd02a2015-02-03 20:07:35 -0800218 break;
219 case PUSH_MPLS:
220 OFActionPushMpls pushMpls = (OFActionPushMpls) act;
221 builder.pushMpls();
222 break;
223 case COPY_TTL_IN:
224 OFActionCopyTtlIn copyTtlIn = (OFActionCopyTtlIn) act;
225 builder.copyTtlIn();
226 break;
227 case COPY_TTL_OUT:
228 OFActionCopyTtlOut copyTtlOut = (OFActionCopyTtlOut) act;
229 builder.copyTtlOut();
230 break;
231 case DEC_MPLS_TTL:
232 OFActionDecMplsTtl decMplsTtl = (OFActionDecMplsTtl) act;
233 builder.decMplsTtl();
234 break;
235 case DEC_NW_TTL:
236 OFActionDecNwTtl decNwTtl = (OFActionDecNwTtl) act;
237 builder.decNwTtl();
238 break;
Saurav Das88329902015-05-27 23:22:32 -0700239 case GROUP:
240 OFActionGroup grp = (OFActionGroup) act;
241 builder.group(new DefaultGroupId(grp.getGroup().getGroupNumber()));
242 break;
sangho5afd02a2015-02-03 20:07:35 -0800243 case SET_TP_DST:
244 case SET_TP_SRC:
245 case POP_PBB:
sangho5afd02a2015-02-03 20:07:35 -0800246 case PUSH_PBB:
sangho5afd02a2015-02-03 20:07:35 -0800247 case SET_MPLS_LABEL:
248 case SET_MPLS_TC:
249 case SET_MPLS_TTL:
250 case SET_NW_ECN:
251 case SET_NW_TOS:
252 case SET_NW_TTL:
253 case SET_QUEUE:
254 case STRIP_VLAN:
255 case ENQUEUE:
sangho5afd02a2015-02-03 20:07:35 -0800256 default:
257 log.warn("Action type {} not yet implemented.", act.getType());
258 }
259 }
260
261 return builder.build();
262 }
263
Hyunsun Moona834c182015-12-16 03:01:56 -0800264 private void handleSetField(TrafficTreatment.Builder builder, OFActionSetField action) {
265 OFOxm<?> oxm = action.getField();
sangho5afd02a2015-02-03 20:07:35 -0800266 switch (oxm.getMatchField().id) {
267 case VLAN_PCP:
268 @SuppressWarnings("unchecked")
269 OFOxm<VlanPcp> vlanpcp = (OFOxm<VlanPcp>) oxm;
270 builder.setVlanPcp(vlanpcp.getValue().getValue());
271 break;
272 case VLAN_VID:
273 @SuppressWarnings("unchecked")
274 OFOxm<OFVlanVidMatch> vlanvid = (OFOxm<OFVlanVidMatch>) oxm;
275 builder.setVlanId(VlanId.vlanId(vlanvid.getValue().getVlan()));
276 break;
277 case ETH_DST:
278 @SuppressWarnings("unchecked")
279 OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethdst =
280 (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
281 builder.setEthDst(MacAddress.valueOf(ethdst.getValue().getLong()));
282 break;
283 case ETH_SRC:
284 @SuppressWarnings("unchecked")
285 OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethsrc =
286 (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
287 builder.setEthSrc(MacAddress.valueOf(ethsrc.getValue().getLong()));
288 break;
289 case IPV4_DST:
290 @SuppressWarnings("unchecked")
291 OFOxm<IPv4Address> ip4dst = (OFOxm<IPv4Address>) oxm;
292 builder.setIpDst(Ip4Address.valueOf(ip4dst.getValue().getInt()));
293 break;
294 case IPV4_SRC:
295 @SuppressWarnings("unchecked")
296 OFOxm<IPv4Address> ip4src = (OFOxm<IPv4Address>) oxm;
297 builder.setIpSrc(Ip4Address.valueOf(ip4src.getValue().getInt()));
298 break;
299 case MPLS_LABEL:
300 @SuppressWarnings("unchecked")
301 OFOxm<U32> labelId = (OFOxm<U32>) oxm;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100302 builder.setMpls(MplsLabel.mplsLabel((int) labelId.getValue().getValue()));
sangho5afd02a2015-02-03 20:07:35 -0800303 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700304 case MPLS_BOS:
305 @SuppressWarnings("unchecked")
306 OFOxm<U8> mplsBos = (OFOxm<U8>) oxm;
307 builder.setMplsBos(mplsBos.getValue() == U8.ZERO ? false : true);
308 break;
Hyunsun Moona834c182015-12-16 03:01:56 -0800309 case TUNNEL_ID:
310 @SuppressWarnings("unchecked")
311 OFOxm<U64> tunnelId = (OFOxm<U64>) oxm;
312 builder.setTunnelId(tunnelId.getValue().getValue());
313 break;
314 case TUNNEL_IPV4_DST:
315 DriverHandler driver = getDriver(dpid);
316 ExtensionTreatmentInterpreter interpreter = driver.behaviour(ExtensionTreatmentInterpreter.class);
317 if (interpreter != null) {
318 builder.extension(interpreter.mapAction(action), DeviceId.deviceId(Dpid.uri(dpid)));
319 }
320 break;
sangho5afd02a2015-02-03 20:07:35 -0800321 case ARP_OP:
322 case ARP_SHA:
323 case ARP_SPA:
324 case ARP_THA:
325 case ARP_TPA:
326 case BSN_EGR_PORT_GROUP_ID:
327 case BSN_GLOBAL_VRF_ALLOWED:
328 case BSN_IN_PORTS_128:
329 case BSN_L3_DST_CLASS_ID:
330 case BSN_L3_INTERFACE_CLASS_ID:
331 case BSN_L3_SRC_CLASS_ID:
332 case BSN_LAG_ID:
333 case BSN_TCP_FLAGS:
334 case BSN_UDF0:
335 case BSN_UDF1:
336 case BSN_UDF2:
337 case BSN_UDF3:
338 case BSN_UDF4:
339 case BSN_UDF5:
340 case BSN_UDF6:
341 case BSN_UDF7:
342 case BSN_VLAN_XLATE_PORT_GROUP_ID:
343 case BSN_VRF:
344 case ETH_TYPE:
345 case ICMPV4_CODE:
346 case ICMPV4_TYPE:
347 case ICMPV6_CODE:
348 case ICMPV6_TYPE:
349 case IN_PHY_PORT:
350 case IN_PORT:
351 case IPV6_DST:
352 case IPV6_FLABEL:
353 case IPV6_ND_SLL:
354 case IPV6_ND_TARGET:
355 case IPV6_ND_TLL:
356 case IPV6_SRC:
357 case IP_DSCP:
358 case IP_ECN:
359 case IP_PROTO:
360 case METADATA:
361 case MPLS_TC:
362 case OCH_SIGID:
363 case OCH_SIGID_BASIC:
364 case OCH_SIGTYPE:
365 case OCH_SIGTYPE_BASIC:
366 case SCTP_DST:
367 case SCTP_SRC:
368 case TCP_DST:
369 case TCP_SRC:
sangho5afd02a2015-02-03 20:07:35 -0800370 case UDP_DST:
371 case UDP_SRC:
372 default:
373 log.warn("Set field type {} not yet implemented.", oxm.getMatchField().id);
374 break;
375 }
376 }
Hyunsun Moona834c182015-12-16 03:01:56 -0800377
378 private DriverHandler getDriver(Dpid dpid) {
379 DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid));
380 Driver driver = driverService.getDriver(deviceId);
381 DriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
382 return handler;
383 }
sangho5afd02a2015-02-03 20:07:35 -0800384}