blob: 37bdc19983769298f4b283d63f3d76915c5e0432 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Jonathan Hart86e59352014-10-22 10:42:16 -070019package org.onlab.onos.provider.of.flow.impl;
20
21import java.util.Collections;
22import java.util.LinkedList;
23import java.util.List;
24
25import org.onlab.onos.net.flow.FlowRule;
26import org.onlab.onos.net.flow.TrafficTreatment;
27import org.onlab.onos.net.flow.instructions.Instruction;
28import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
29import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
30import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
31import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
32import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
33import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
34import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
35import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
36import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
37import org.projectfloodlight.openflow.protocol.OFFactory;
38import org.projectfloodlight.openflow.protocol.OFFlowAdd;
39import org.projectfloodlight.openflow.protocol.OFFlowDelete;
40import org.projectfloodlight.openflow.protocol.OFFlowMod;
41import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
42import org.projectfloodlight.openflow.protocol.action.OFAction;
Jonathan Hart86e59352014-10-22 10:42:16 -070043import org.projectfloodlight.openflow.protocol.match.Match;
44import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
45import org.projectfloodlight.openflow.types.CircuitSignalID;
46import org.projectfloodlight.openflow.types.IPv4Address;
47import org.projectfloodlight.openflow.types.MacAddress;
48import org.projectfloodlight.openflow.types.OFBufferId;
49import org.projectfloodlight.openflow.types.OFPort;
50import org.projectfloodlight.openflow.types.OFVlanVidMatch;
51import org.projectfloodlight.openflow.types.U64;
52import org.projectfloodlight.openflow.types.VlanPcp;
53import org.slf4j.Logger;
54import org.slf4j.LoggerFactory;
55
56/**
57 * Flow mod builder for OpenFlow 1.3+.
58 */
59public class FlowModBuilderVer13 extends FlowModBuilder {
60
61 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
62
63 private final TrafficTreatment treatment;
64
65 /**
66 * Constructor for a flow mod builder for OpenFlow 1.3.
67 *
68 * @param flowRule the flow rule to transform into a flow mod
69 * @param factory the OpenFlow factory to use to build the flow mod
70 */
71 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory) {
72 super(flowRule, factory);
73
74 this.treatment = flowRule.treatment();
75 }
76
77 @Override
78 public OFFlowAdd buildFlowAdd() {
79 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070080 List<OFAction> actions = buildActions();
81
82 // FIXME had to revert back to using apply-actions instead of
83 // write-actions because LINC-OE apparently doesn't support
84 // write-actions. I would prefer to change this back in the future
85 // because apply-actions is an optional instruction in OF 1.3.
86
87 //OFInstruction writeActions =
88 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -070089
90 long cookie = flowRule().id().value();
91
92 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
93 OFFlowAdd fm = factory().buildFlowAdd()
94 .setXid(cookie)
95 .setCookie(U64.of(cookie))
96 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070097 .setActions(actions)
98 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -070099 .setMatch(match)
100 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
101 .setPriority(flowRule().priority())
102 .build();
103
104 return fm;
105 }
106
107 @Override
108 public OFFlowMod buildFlowMod() {
109 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700110 List<OFAction> actions = buildActions();
111 //OFInstruction writeActions =
112 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700113
114 long cookie = flowRule().id().value();
115
116 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
117 OFFlowMod fm = factory().buildFlowModify()
118 .setXid(cookie)
119 .setCookie(U64.of(cookie))
120 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700121 .setActions(actions)
122 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700123 .setMatch(match)
124 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
125 .setPriority(flowRule().priority())
126 .build();
127
128 return fm;
129 }
130
131 @Override
132 public OFFlowDelete buildFlowDel() {
133 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700134 List<OFAction> actions = buildActions();
135 //OFInstruction writeActions =
136 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700137
138 long cookie = flowRule().id().value();
139
140 OFFlowDelete fm = factory().buildFlowDelete()
141 .setXid(cookie)
142 .setCookie(U64.of(cookie))
143 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700144 .setActions(actions)
145 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700146 .setMatch(match)
147 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
148 .setPriority(flowRule().priority())
149 .build();
150
151 return fm;
152 }
153
154 private List<OFAction> buildActions() {
155 List<OFAction> actions = new LinkedList<>();
156 if (treatment == null) {
157 return actions;
158 }
159 for (Instruction i : treatment.instructions()) {
160 switch (i.type()) {
161 case DROP:
162 log.warn("Saw drop action; assigning drop action");
163 return new LinkedList<>();
164 case L0MODIFICATION:
165 actions.add(buildL0Modification(i));
166 break;
167 case L2MODIFICATION:
168 actions.add(buildL2Modification(i));
169 break;
170 case L3MODIFICATION:
171 actions.add(buildL3Modification(i));
172 break;
173 case OUTPUT:
174 OutputInstruction out = (OutputInstruction) i;
175 actions.add(factory().actions().buildOutput().setPort(
176 OFPort.of((int) out.port().toLong())).build());
177 break;
178 case GROUP:
179 default:
180 log.warn("Instruction type {} not yet implemented.", i.type());
181 }
182 }
183
184 return actions;
185 }
186
187 private OFAction buildL0Modification(Instruction i) {
188 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
189 switch (l0m.subtype()) {
190 case LAMBDA:
191 ModLambdaInstruction ml = (ModLambdaInstruction) i;
192 return factory().actions().circuit(factory().oxms().ochSigidBasic(
193 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
194 default:
195 log.warn("Unimplemented action type {}.", l0m.subtype());
196 break;
197 }
198 return null;
199 }
200
201 private OFAction buildL2Modification(Instruction i) {
202 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
203 ModEtherInstruction eth;
204 OFOxm<?> oxm = null;
205 switch (l2m.subtype()) {
206 case ETH_DST:
207 eth = (ModEtherInstruction) l2m;
208 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
209 break;
210 case ETH_SRC:
211 eth = (ModEtherInstruction) l2m;
212 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
213 break;
214 case VLAN_ID:
215 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
216 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId.toShort()));
217 break;
218 case VLAN_PCP:
219 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
220 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp));
221 break;
222 default:
223 log.warn("Unimplemented action type {}.", l2m.subtype());
224 break;
225 }
226
227 if (oxm != null) {
228 return factory().actions().buildSetField().setField(oxm).build();
229 }
230 return null;
231 }
232
233 private OFAction buildL3Modification(Instruction i) {
234 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
235 ModIPInstruction ip;
236 OFOxm<?> oxm = null;
237 switch (l3m.subtype()) {
238 case IP_DST:
239 ip = (ModIPInstruction) i;
240 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip.ip().toInt()));
241 case IP_SRC:
242 ip = (ModIPInstruction) i;
243 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip.ip().toInt()));
244 default:
245 log.warn("Unimplemented action type {}.", l3m.subtype());
246 break;
247 }
248
249 if (oxm != null) {
250 return factory().actions().buildSetField().setField(oxm).build();
251 }
252 return null;
253 }
254
255}