b9de7c0f1e1ed28fdd9c073218f1668668e5a9f2
[onosfw.git] /
1 /*
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  */
16 package org.onosproject.provider.of.group.impl;
17
18 import com.google.common.collect.Lists;
19
20 import org.onlab.packet.Ip4Address;
21 import org.onlab.packet.MacAddress;
22 import org.onlab.packet.MplsLabel;
23 import org.onlab.packet.VlanId;
24 import org.onosproject.core.DefaultGroupId;
25 import org.onosproject.core.GroupId;
26 import org.onosproject.net.Lambda;
27 import org.onosproject.net.PortNumber;
28 import org.onosproject.net.flow.DefaultTrafficTreatment;
29 import org.onosproject.net.flow.TrafficTreatment;
30 import org.onosproject.net.flow.instructions.Instructions;
31 import org.onosproject.net.group.DefaultGroupBucket;
32 import org.onosproject.net.group.GroupBucket;
33 import org.onosproject.net.group.GroupBuckets;
34 import org.projectfloodlight.openflow.protocol.OFBucket;
35 import org.projectfloodlight.openflow.protocol.OFGroupType;
36 import org.projectfloodlight.openflow.protocol.action.OFAction;
37 import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
38 import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlIn;
39 import org.projectfloodlight.openflow.protocol.action.OFActionCopyTtlOut;
40 import org.projectfloodlight.openflow.protocol.action.OFActionDecMplsTtl;
41 import org.projectfloodlight.openflow.protocol.action.OFActionDecNwTtl;
42 import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
43 import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
44 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
45 import org.projectfloodlight.openflow.protocol.action.OFActionPopMpls;
46 import org.projectfloodlight.openflow.protocol.action.OFActionPushMpls;
47 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
48 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
49 import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
50 import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
51 import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
52 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
53 import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
54 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
55 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
56 import org.projectfloodlight.openflow.types.IPv4Address;
57 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
58 import org.projectfloodlight.openflow.types.U32;
59 import org.projectfloodlight.openflow.types.U8;
60 import org.projectfloodlight.openflow.types.VlanPcp;
61 import org.slf4j.Logger;
62
63 import java.util.List;
64
65 import static org.slf4j.LoggerFactory.getLogger;
66
67 /*
68  * Builder for GroupBucketEntry.
69  */
70 public class GroupBucketEntryBuilder {
71
72     private List<OFBucket> ofBuckets;
73     private OFGroupType type;
74
75     private final Logger log = getLogger(getClass());
76
77     /**
78      * Creates a builder.
79      *
80      * @param ofBuckets list of OFBucket
81      * @param type Group type
82      */
83     public GroupBucketEntryBuilder(List<OFBucket> ofBuckets, OFGroupType type) {
84         this.ofBuckets = ofBuckets;
85         this.type = type;
86     }
87
88     /**
89      * Builds a GroupBuckets.
90      *
91      * @return GroupBuckets object, a list of GroupBuckets
92      */
93     public GroupBuckets build() {
94         List<GroupBucket> bucketList = Lists.newArrayList();
95
96         for (OFBucket bucket: ofBuckets) {
97             TrafficTreatment treatment = buildTreatment(bucket.getActions());
98             // TODO: Use GroupBucketEntry
99             GroupBucket groupBucket = null;
100             switch (type) {
101                 case INDIRECT:
102                     groupBucket =
103                             DefaultGroupBucket.createIndirectGroupBucket(treatment);
104                     break;
105                 case SELECT:
106                     groupBucket =
107                             DefaultGroupBucket.createSelectGroupBucket(treatment);
108                     break;
109                 case FF:
110                     PortNumber port =
111                             PortNumber.portNumber(bucket.getWatchPort().getPortNumber());
112                     GroupId groupId =
113                             new DefaultGroupId(bucket.getWatchGroup().getGroupNumber());
114                     groupBucket =
115                             DefaultGroupBucket.createFailoverGroupBucket(treatment,
116                                     port, groupId);
117                     break;
118                 default:
119                     log.error("Unsupported Group type : {}", type);
120             }
121             if (groupBucket != null) {
122                 bucketList.add(groupBucket);
123             }
124         }
125         return new GroupBuckets(bucketList);
126     }
127
128
129     private TrafficTreatment buildTreatment(List<OFAction> actions) {
130         TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
131         // If this is a drop rule
132         if (actions.size() == 0) {
133             builder.drop();
134             return builder.build();
135         }
136         for (OFAction act : actions) {
137             switch (act.getType()) {
138                 case OUTPUT:
139                     OFActionOutput out = (OFActionOutput) act;
140                     builder.setOutput(
141                             PortNumber.portNumber(out.getPort().getPortNumber()));
142                     break;
143                 case SET_VLAN_VID:
144                     OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
145                     builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan()));
146                     break;
147                 case SET_VLAN_PCP:
148                     OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
149                     builder.setVlanPcp(pcp.getVlanPcp().getValue());
150                     break;
151                 case POP_VLAN:
152                     builder.popVlan();
153                     break;
154                 case PUSH_VLAN:
155                     builder.pushVlan();
156                     break;
157                 case SET_DL_DST:
158                     OFActionSetDlDst dldst = (OFActionSetDlDst) act;
159                     builder.setEthDst(
160                             MacAddress.valueOf(dldst.getDlAddr().getLong()));
161                     break;
162                 case SET_DL_SRC:
163                     OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
164                     builder.setEthSrc(
165                             MacAddress.valueOf(dlsrc.getDlAddr().getLong()));
166
167                     break;
168                 case SET_NW_DST:
169                     OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
170                     IPv4Address di = nwdst.getNwAddr();
171                     builder.setIpDst(Ip4Address.valueOf(di.getInt()));
172                     break;
173                 case SET_NW_SRC:
174                     OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
175                     IPv4Address si = nwsrc.getNwAddr();
176                     builder.setIpSrc(Ip4Address.valueOf(si.getInt()));
177                     break;
178                 case EXPERIMENTER:
179                     OFActionExperimenter exp = (OFActionExperimenter) act;
180                     if (exp.getExperimenter() == 0x80005A06 ||
181                             exp.getExperimenter() == 0x748771) {
182                         OFActionCircuit ct = (OFActionCircuit) exp;
183                         short lambda = ((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber();
184                         builder.add(Instructions.modL0Lambda(Lambda.indexedLambda(lambda)));
185                     } else {
186                         log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter());
187                     }
188                     break;
189                 case SET_FIELD:
190                     OFActionSetField setField = (OFActionSetField) act;
191                     handleSetField(builder, setField.getField());
192                     break;
193                 case POP_MPLS:
194                     OFActionPopMpls popMpls = (OFActionPopMpls) act;
195                     builder.popMpls((short) popMpls.getEthertype().getValue());
196                     break;
197                 case PUSH_MPLS:
198                     OFActionPushMpls pushMpls = (OFActionPushMpls) act;
199                     builder.pushMpls();
200                     break;
201                 case COPY_TTL_IN:
202                     OFActionCopyTtlIn copyTtlIn = (OFActionCopyTtlIn) act;
203                     builder.copyTtlIn();
204                     break;
205                 case COPY_TTL_OUT:
206                     OFActionCopyTtlOut copyTtlOut = (OFActionCopyTtlOut) act;
207                     builder.copyTtlOut();
208                     break;
209                 case DEC_MPLS_TTL:
210                     OFActionDecMplsTtl decMplsTtl = (OFActionDecMplsTtl) act;
211                     builder.decMplsTtl();
212                     break;
213                 case DEC_NW_TTL:
214                     OFActionDecNwTtl decNwTtl = (OFActionDecNwTtl) act;
215                     builder.decNwTtl();
216                     break;
217                 case GROUP:
218                     OFActionGroup grp = (OFActionGroup) act;
219                     builder.group(new DefaultGroupId(grp.getGroup().getGroupNumber()));
220                     break;
221                 case SET_TP_DST:
222                 case SET_TP_SRC:
223                 case POP_PBB:
224                 case PUSH_PBB:
225                 case SET_MPLS_LABEL:
226                 case SET_MPLS_TC:
227                 case SET_MPLS_TTL:
228                 case SET_NW_ECN:
229                 case SET_NW_TOS:
230                 case SET_NW_TTL:
231                 case SET_QUEUE:
232                 case STRIP_VLAN:
233                 case ENQUEUE:
234                 default:
235                     log.warn("Action type {} not yet implemented.", act.getType());
236             }
237         }
238
239         return builder.build();
240     }
241
242     private void handleSetField(TrafficTreatment.Builder builder, OFOxm<?> oxm) {
243         switch (oxm.getMatchField().id) {
244             case VLAN_PCP:
245                 @SuppressWarnings("unchecked")
246                 OFOxm<VlanPcp> vlanpcp = (OFOxm<VlanPcp>) oxm;
247                 builder.setVlanPcp(vlanpcp.getValue().getValue());
248                 break;
249             case VLAN_VID:
250                 @SuppressWarnings("unchecked")
251                 OFOxm<OFVlanVidMatch> vlanvid = (OFOxm<OFVlanVidMatch>) oxm;
252                 builder.setVlanId(VlanId.vlanId(vlanvid.getValue().getVlan()));
253                 break;
254             case ETH_DST:
255                 @SuppressWarnings("unchecked")
256                 OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethdst =
257                         (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
258                 builder.setEthDst(MacAddress.valueOf(ethdst.getValue().getLong()));
259                 break;
260             case ETH_SRC:
261                 @SuppressWarnings("unchecked")
262                 OFOxm<org.projectfloodlight.openflow.types.MacAddress> ethsrc =
263                         (OFOxm<org.projectfloodlight.openflow.types.MacAddress>) oxm;
264                 builder.setEthSrc(MacAddress.valueOf(ethsrc.getValue().getLong()));
265                 break;
266             case IPV4_DST:
267                 @SuppressWarnings("unchecked")
268                 OFOxm<IPv4Address> ip4dst = (OFOxm<IPv4Address>) oxm;
269                 builder.setIpDst(Ip4Address.valueOf(ip4dst.getValue().getInt()));
270                 break;
271             case IPV4_SRC:
272                 @SuppressWarnings("unchecked")
273                 OFOxm<IPv4Address> ip4src = (OFOxm<IPv4Address>) oxm;
274                 builder.setIpSrc(Ip4Address.valueOf(ip4src.getValue().getInt()));
275                 break;
276             case MPLS_LABEL:
277                 @SuppressWarnings("unchecked")
278                 OFOxm<U32> labelId = (OFOxm<U32>) oxm;
279                 builder.setMpls(MplsLabel.mplsLabel((int) labelId.getValue().getValue()));
280                 break;
281             case MPLS_BOS:
282                 @SuppressWarnings("unchecked")
283                 OFOxm<U8> mplsBos = (OFOxm<U8>) oxm;
284                 builder.setMplsBos(mplsBos.getValue() == U8.ZERO ? false : true);
285                 break;
286             case ARP_OP:
287             case ARP_SHA:
288             case ARP_SPA:
289             case ARP_THA:
290             case ARP_TPA:
291             case BSN_EGR_PORT_GROUP_ID:
292             case BSN_GLOBAL_VRF_ALLOWED:
293             case BSN_IN_PORTS_128:
294             case BSN_L3_DST_CLASS_ID:
295             case BSN_L3_INTERFACE_CLASS_ID:
296             case BSN_L3_SRC_CLASS_ID:
297             case BSN_LAG_ID:
298             case BSN_TCP_FLAGS:
299             case BSN_UDF0:
300             case BSN_UDF1:
301             case BSN_UDF2:
302             case BSN_UDF3:
303             case BSN_UDF4:
304             case BSN_UDF5:
305             case BSN_UDF6:
306             case BSN_UDF7:
307             case BSN_VLAN_XLATE_PORT_GROUP_ID:
308             case BSN_VRF:
309             case ETH_TYPE:
310             case ICMPV4_CODE:
311             case ICMPV4_TYPE:
312             case ICMPV6_CODE:
313             case ICMPV6_TYPE:
314             case IN_PHY_PORT:
315             case IN_PORT:
316             case IPV6_DST:
317             case IPV6_FLABEL:
318             case IPV6_ND_SLL:
319             case IPV6_ND_TARGET:
320             case IPV6_ND_TLL:
321             case IPV6_SRC:
322             case IP_DSCP:
323             case IP_ECN:
324             case IP_PROTO:
325             case METADATA:
326             case MPLS_TC:
327             case OCH_SIGID:
328             case OCH_SIGID_BASIC:
329             case OCH_SIGTYPE:
330             case OCH_SIGTYPE_BASIC:
331             case SCTP_DST:
332             case SCTP_SRC:
333             case TCP_DST:
334             case TCP_SRC:
335             case TUNNEL_ID:
336             case UDP_DST:
337             case UDP_SRC:
338             default:
339                 log.warn("Set field type {} not yet implemented.", oxm.getMatchField().id);
340                 break;
341         }
342     }
343 }