blob: db30d96b0abfbde754955df7a453a4864cd3fe7e [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
sangho5afd02a2015-02-03 20:07:35 -080020import org.onlab.packet.Ip4Address;
21import org.onlab.packet.MacAddress;
Michele Santuari4b6019e2014-12-19 11:31:45 +010022import org.onlab.packet.MplsLabel;
sangho5afd02a2015-02-03 20:07:35 -080023import org.onlab.packet.VlanId;
24import org.onosproject.core.DefaultGroupId;
25import org.onosproject.core.GroupId;
Hyunsun Moona834c182015-12-16 03:01:56 -080026import org.onosproject.net.DeviceId;
Sho SHIMIZU9553bb82015-06-30 16:02:45 -070027import org.onosproject.net.Lambda;
sangho5afd02a2015-02-03 20:07:35 -080028import org.onosproject.net.PortNumber;
Hyunsun Moona834c182015-12-16 03:01:56 -080029import org.onosproject.net.driver.DefaultDriverData;
30import org.onosproject.net.driver.DefaultDriverHandler;
31import org.onosproject.net.driver.Driver;
32import org.onosproject.net.driver.DriverHandler;
33import org.onosproject.net.driver.DriverService;
sangho5afd02a2015-02-03 20:07:35 -080034import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.TrafficTreatment;
Sho SHIMIZU9553bb82015-06-30 16:02:45 -070036import org.onosproject.net.flow.instructions.Instructions;
sangho5afd02a2015-02-03 20:07:35 -080037import org.onosproject.net.group.DefaultGroupBucket;
38import org.onosproject.net.group.GroupBucket;
39import org.onosproject.net.group.GroupBuckets;
Hyunsun Moona834c182015-12-16 03:01:56 -080040import org.onosproject.openflow.controller.Dpid;
41import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
sangho5afd02a2015-02-03 20:07:35 -080042import org.projectfloodlight.openflow.protocol.OFBucket;
43import org.projectfloodlight.openflow.protocol.OFGroupType;
44import org.projectfloodlight.openflow.protocol.action.OFAction;
45import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
46import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlIn;
47import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlOut;
48import org.projectfloodlight.openflow.protocol.action.OFActionDecMplsTtl;
49import org.projectfloodlight.openflow.protocol.action.OFActionDecNwTtl;
50import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
Saurav Das88329902015-05-27 23:22:32 -070051import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
sangho5afd02a2015-02-03 20:07:35 -080052import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
53import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls;
54import org.projectfloodlight.openflow.protocol.action.OFActionPushMpls;
55import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
56import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
57import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
58import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
59import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
60import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
61import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
62import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
63import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
64import org.projectfloodlight.openflow.types.IPv4Address;
65import org.projectfloodlight.openflow.types.OFVlanVidMatch;
66import org.projectfloodlight.openflow.types.U32;
Hyunsun Moona834c182015-12-16 03:01:56 -080067import org.projectfloodlight.openflow.types.U64;
Saurav Das73a7dd42015-08-19 22:20:31 -070068import org.projectfloodlight.openflow.types.U8;
sangho5afd02a2015-02-03 20:07:35 -080069import org.projectfloodlight.openflow.types.VlanPcp;
70import org.slf4j.Logger;
71
72import java.util.List;
73
74import static org.slf4j.LoggerFactory.getLogger;
75
76/*
77 * Builder for GroupBucketEntry.
78 */
79public class GroupBucketEntryBuilder {
80
Hyunsun Moona834c182015-12-16 03:01:56 -080081 private Dpid dpid;
sangho5afd02a2015-02-03 20:07:35 -080082 private List<OFBucket> ofBuckets;
83 private OFGroupType type;
Hyunsun Moona834c182015-12-16 03:01:56 -080084 private DriverService driverService;
sangho5afd02a2015-02-03 20:07:35 -080085
86 private final Logger log = getLogger(getClass());
87
Hyunsun Moona834c182015-12-16 03:01:56 -080088
sangho5afd02a2015-02-03 20:07:35 -080089 /**
90 * Creates a builder.
91 *
Hyunsun Moona834c182015-12-16 03:01:56 -080092 * @param dpid dpid
sangho5afd02a2015-02-03 20:07:35 -080093 * @param ofBuckets list of OFBucket
94 * @param type Group type
Hyunsun Moona834c182015-12-16 03:01:56 -080095 * @param driverService driver service
sangho5afd02a2015-02-03 20:07:35 -080096 */
Hyunsun Moona834c182015-12-16 03:01:56 -080097 public GroupBucketEntryBuilder(Dpid dpid, List<OFBucket> ofBuckets, OFGroupType type,
98 DriverService driverService) {
99 this.dpid = dpid;
sangho5afd02a2015-02-03 20:07:35 -0800100 this.ofBuckets = ofBuckets;
101 this.type = type;
Hyunsun Moona834c182015-12-16 03:01:56 -0800102 this.driverService = driverService;
sangho5afd02a2015-02-03 20:07:35 -0800103 }
104
105 /**
106 * Builds a GroupBuckets.
107 *
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700108 * @return GroupBuckets object, a list of GroupBuckets
sangho5afd02a2015-02-03 20:07:35 -0800109 */
110 public GroupBuckets build() {
111 List<GroupBucket> bucketList = Lists.newArrayList();
112
113 for (OFBucket bucket: ofBuckets) {
114 TrafficTreatment treatment = buildTreatment(bucket.getActions());
115 // TODO: Use GroupBucketEntry
116 GroupBucket groupBucket = null;
117 switch (type) {
118 case INDIRECT:
119 groupBucket =
120 DefaultGroupBucket.createIndirectGroupBucket(treatment);
121 break;
122 case SELECT:
123 groupBucket =
124 DefaultGroupBucket.createSelectGroupBucket(treatment);
125 break;
126 case FF:
127 PortNumber port =
128 PortNumber.portNumber(bucket.getWatchPort().getPortNumber());
129 GroupId groupId =
130 new DefaultGroupId(bucket.getWatchGroup().getGroupNumber());
131 groupBucket =
132 DefaultGroupBucket.createFailoverGroupBucket(treatment,
133 port, groupId);
134 break;
Charles Chanc42e84e2015-10-20 16:24:19 -0700135 case ALL:
136 groupBucket =
137 DefaultGroupBucket.createAllGroupBucket(treatment);
138 break;
sangho5afd02a2015-02-03 20:07:35 -0800139 default:
140 log.error("Unsupported Group type : {}", type);
141 }
142 if (groupBucket != null) {
143 bucketList.add(groupBucket);
144 }
145 }
146 return new GroupBuckets(bucketList);
147 }
148
149
150 private TrafficTreatment buildTreatment(List<OFAction> actions) {
151 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
152 // If this is a drop rule
153 if (actions.size() == 0) {
154 builder.drop();
155 return builder.build();
156 }
157 for (OFAction act : actions) {
158 switch (act.getType()) {
159 case OUTPUT:
160 OFActionOutput out = (OFActionOutput) act;
161 builder.setOutput(
162 PortNumber.portNumber(out.getPort().getPortNumber()));
163 break;
164 case SET_VLAN_VID:
165 OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
166 builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan()));
167 break;
168 case SET_VLAN_PCP:
169 OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
170 builder.setVlanPcp(pcp.getVlanPcp().getValue());
171 break;
Jonathan Harte106e4b2015-03-09 16:44:56 -0700172 case POP_VLAN:
173 builder.popVlan();
174 break;
175 case PUSH_VLAN:
176 builder.pushVlan();
177 break;
sangho5afd02a2015-02-03 20:07:35 -0800178 case SET_DL_DST:
179 OFActionSetDlDst dldst = (OFActionSetDlDst) act;
180 builder.setEthDst(
181 MacAddress.valueOf(dldst.getDlAddr().getLong()));
182 break;
183 case SET_DL_SRC:
184 OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
185 builder.setEthSrc(
186 MacAddress.valueOf(dlsrc.getDlAddr().getLong()));
187
188 break;
189 case SET_NW_DST:
190 OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
191 IPv4Address di = nwdst.getNwAddr();
192 builder.setIpDst(Ip4Address.valueOf(di.getInt()));
193 break;
194 case SET_NW_SRC:
195 OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
196 IPv4Address si = nwsrc.getNwAddr();
197 builder.setIpSrc(Ip4Address.valueOf(si.getInt()));
198 break;
199 case EXPERIMENTER:
200 OFActionExperimenter exp = (OFActionExperimenter) act;
201 if (exp.getExperimenter() == 0x80005A06 ||
202 exp.getExperimenter() == 0x748771) {
203 OFActionCircuit ct = (OFActionCircuit) exp;
Sho SHIMIZU9553bb82015-06-30 16:02:45 -0700204 short lambda = ((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber();
205 builder.add(Instructions.modL0Lambda(Lambda.indexedLambda(lambda)));
sangho5afd02a2015-02-03 20:07:35 -0800206 } else {
207 log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter());
208 }
209 break;
210 case SET_FIELD:
211 OFActionSetField setField = (OFActionSetField) act;
Hyunsun Moona834c182015-12-16 03:01:56 -0800212 handleSetField(builder, setField);
sangho5afd02a2015-02-03 20:07:35 -0800213 break;
214 case POP_MPLS:
215 OFActionPopMpls popMpls = (OFActionPopMpls) act;
216 builder.popMpls((short) popMpls.getEthertype().getValue());
217 break;
218 case PUSH_MPLS:
219 OFActionPushMpls pushMpls = (OFActionPushMpls) act;
220 builder.pushMpls();
221 break;
222 case COPY_TTL_IN:
223 OFActionCopyTtlIn copyTtlIn = (OFActionCopyTtlIn) act;
224 builder.copyTtlIn();
225 break;
226 case COPY_TTL_OUT:
227 OFActionCopyTtlOut copyTtlOut = (OFActionCopyTtlOut) act;
228 builder.copyTtlOut();
229 break;
230 case DEC_MPLS_TTL:
231 OFActionDecMplsTtl decMplsTtl = (OFActionDecMplsTtl) act;
232 builder.decMplsTtl();
233 break;
234 case DEC_NW_TTL:
235 OFActionDecNwTtl decNwTtl = (OFActionDecNwTtl) act;
236 builder.decNwTtl();
237 break;
Saurav Das88329902015-05-27 23:22:32 -0700238 case GROUP:
239 OFActionGroup grp = (OFActionGroup) act;
240 builder.group(new DefaultGroupId(grp.getGroup().getGroupNumber()));
241 break;
sangho5afd02a2015-02-03 20:07:35 -0800242 case SET_TP_DST:
243 case SET_TP_SRC:
244 case POP_PBB:
sangho5afd02a2015-02-03 20:07:35 -0800245 case PUSH_PBB:
sangho5afd02a2015-02-03 20:07:35 -0800246 case SET_MPLS_LABEL:
247 case SET_MPLS_TC:
248 case SET_MPLS_TTL:
249 case SET_NW_ECN:
250 case SET_NW_TOS:
251 case SET_NW_TTL:
252 case SET_QUEUE:
253 case STRIP_VLAN:
254 case ENQUEUE:
sangho5afd02a2015-02-03 20:07:35 -0800255 default:
256 log.warn("Action type {} not yet implemented.", act.getType());
257 }
258 }
259
260 return builder.build();
261 }
262
Hyunsun Moona834c182015-12-16 03:01:56 -0800263 private void handleSetField(TrafficTreatment.Builder builder, OFActionSetField action) {
264 OFOxm<?> oxm = action.getField();
sangho5afd02a2015-02-03 20:07:35 -0800265 switch (oxm.getMatchField().id) {
266 case VLAN_PCP:
267 @SuppressWarnings("unchecked")
268 OFOxm<VlanPcp> vlanpcp = (OFOxm<VlanPcp>) oxm;
269 builder.setVlanPcp(vlanpcp.getValue().getValue());
270 break;
271 case VLAN_VID:
272 @SuppressWarnings("unchecked")
273 OFOxm<OFVlanVidMatch> vlanvid = (OFOxm<OFVlanVidMatch>) oxm;
274 builder.setVlanId(VlanId.vlanId(vlanvid.getValue().getVlan()));
275 break;
276 case ETH_DST:
277 @SuppressWarnings("unchecked")
278 OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethdst =
279 (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
280 builder.setEthDst(MacAddress.valueOf(ethdst.getValue().getLong()));
281 break;
282 case ETH_SRC:
283 @SuppressWarnings("unchecked")
284 OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethsrc =
285 (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
286 builder.setEthSrc(MacAddress.valueOf(ethsrc.getValue().getLong()));
287 break;
288 case IPV4_DST:
289 @SuppressWarnings("unchecked")
290 OFOxm<IPv4Address> ip4dst = (OFOxm<IPv4Address>) oxm;
291 builder.setIpDst(Ip4Address.valueOf(ip4dst.getValue().getInt()));
292 break;
293 case IPV4_SRC:
294 @SuppressWarnings("unchecked")
295 OFOxm<IPv4Address> ip4src = (OFOxm<IPv4Address>) oxm;
296 builder.setIpSrc(Ip4Address.valueOf(ip4src.getValue().getInt()));
297 break;
298 case MPLS_LABEL:
299 @SuppressWarnings("unchecked")
300 OFOxm<U32> labelId = (OFOxm<U32>) oxm;
Michele Santuari4b6019e2014-12-19 11:31:45 +0100301 builder.setMpls(MplsLabel.mplsLabel((int) labelId.getValue().getValue()));
sangho5afd02a2015-02-03 20:07:35 -0800302 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700303 case MPLS_BOS:
304 @SuppressWarnings("unchecked")
305 OFOxm<U8> mplsBos = (OFOxm<U8>) oxm;
306 builder.setMplsBos(mplsBos.getValue() == U8.ZERO ? false : true);
307 break;
Hyunsun Moona834c182015-12-16 03:01:56 -0800308 case TUNNEL_ID:
309 @SuppressWarnings("unchecked")
310 OFOxm<U64> tunnelId = (OFOxm<U64>) oxm;
311 builder.setTunnelId(tunnelId.getValue().getValue());
312 break;
313 case TUNNEL_IPV4_DST:
314 DriverHandler driver = getDriver(dpid);
315 ExtensionTreatmentInterpreter interpreter = driver.behaviour(ExtensionTreatmentInterpreter.class);
316 if (interpreter != null) {
317 builder.extension(interpreter.mapAction(action), DeviceId.deviceId(Dpid.uri(dpid)));
318 }
319 break;
sangho5afd02a2015-02-03 20:07:35 -0800320 case ARP_OP:
321 case ARP_SHA:
322 case ARP_SPA:
323 case ARP_THA:
324 case ARP_TPA:
325 case BSN_EGR_PORT_GROUP_ID:
326 case BSN_GLOBAL_VRF_ALLOWED:
327 case BSN_IN_PORTS_128:
328 case BSN_L3_DST_CLASS_ID:
329 case BSN_L3_INTERFACE_CLASS_ID:
330 case BSN_L3_SRC_CLASS_ID:
331 case BSN_LAG_ID:
332 case BSN_TCP_FLAGS:
333 case BSN_UDF0:
334 case BSN_UDF1:
335 case BSN_UDF2:
336 case BSN_UDF3:
337 case BSN_UDF4:
338 case BSN_UDF5:
339 case BSN_UDF6:
340 case BSN_UDF7:
341 case BSN_VLAN_XLATE_PORT_GROUP_ID:
342 case BSN_VRF:
343 case ETH_TYPE:
344 case ICMPV4_CODE:
345 case ICMPV4_TYPE:
346 case ICMPV6_CODE:
347 case ICMPV6_TYPE:
348 case IN_PHY_PORT:
349 case IN_PORT:
350 case IPV6_DST:
351 case IPV6_FLABEL:
352 case IPV6_ND_SLL:
353 case IPV6_ND_TARGET:
354 case IPV6_ND_TLL:
355 case IPV6_SRC:
356 case IP_DSCP:
357 case IP_ECN:
358 case IP_PROTO:
359 case METADATA:
360 case MPLS_TC:
361 case OCH_SIGID:
362 case OCH_SIGID_BASIC:
363 case OCH_SIGTYPE:
364 case OCH_SIGTYPE_BASIC:
365 case SCTP_DST:
366 case SCTP_SRC:
367 case TCP_DST:
368 case TCP_SRC:
sangho5afd02a2015-02-03 20:07:35 -0800369 case UDP_DST:
370 case UDP_SRC:
371 default:
372 log.warn("Set field type {} not yet implemented.", oxm.getMatchField().id);
373 break;
374 }
375 }
Hyunsun Moona834c182015-12-16 03:01:56 -0800376
377 private DriverHandler getDriver(Dpid dpid) {
378 DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid));
379 Driver driver = driverService.getDriver(deviceId);
380 DriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
381 return handler;
382 }
sangho5afd02a2015-02-03 20:07:35 -0800383}