blob: 6de56c3079449b4a6915dedffcb8e5a36fb1ce0a [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Jonathan Hart86e59352014-10-22 10:42:16 -070016package org.onlab.onos.provider.of.flow.impl;
17
18import java.util.Collections;
19import java.util.LinkedList;
20import java.util.List;
Brian O'Connor427a1762014-11-19 18:40:32 -080021import java.util.Optional;
Jonathan Hart86e59352014-10-22 10:42:16 -070022
23import org.onlab.onos.net.flow.FlowRule;
24import org.onlab.onos.net.flow.TrafficTreatment;
25import org.onlab.onos.net.flow.instructions.Instruction;
26import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
27import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
28import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
29import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
30import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
31import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
32import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080033import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
34import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
Jonathan Hart86e59352014-10-22 10:42:16 -070035import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
36import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -080037import org.onlab.packet.Ip4Address;
Jonathan Hart86e59352014-10-22 10:42:16 -070038import org.projectfloodlight.openflow.protocol.OFFactory;
39import org.projectfloodlight.openflow.protocol.OFFlowAdd;
40import org.projectfloodlight.openflow.protocol.OFFlowDelete;
41import org.projectfloodlight.openflow.protocol.OFFlowMod;
42import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
43import org.projectfloodlight.openflow.protocol.action.OFAction;
Jonathan Hart86e59352014-10-22 10:42:16 -070044import org.projectfloodlight.openflow.protocol.match.Match;
45import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
46import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080047import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070048import org.projectfloodlight.openflow.types.IPv4Address;
49import org.projectfloodlight.openflow.types.MacAddress;
50import org.projectfloodlight.openflow.types.OFBufferId;
51import org.projectfloodlight.openflow.types.OFPort;
52import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080053import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070054import org.projectfloodlight.openflow.types.U64;
55import org.projectfloodlight.openflow.types.VlanPcp;
56import org.slf4j.Logger;
57import org.slf4j.LoggerFactory;
58
59/**
60 * Flow mod builder for OpenFlow 1.3+.
61 */
62public class FlowModBuilderVer13 extends FlowModBuilder {
63
64 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
65
66 private final TrafficTreatment treatment;
67
68 /**
69 * Constructor for a flow mod builder for OpenFlow 1.3.
70 *
71 * @param flowRule the flow rule to transform into a flow mod
72 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080073 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070074 */
Brian O'Connor427a1762014-11-19 18:40:32 -080075 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
76 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070077
78 this.treatment = flowRule.treatment();
79 }
80
81 @Override
82 public OFFlowAdd buildFlowAdd() {
83 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070084 List<OFAction> actions = buildActions();
85
86 // FIXME had to revert back to using apply-actions instead of
87 // write-actions because LINC-OE apparently doesn't support
88 // write-actions. I would prefer to change this back in the future
89 // because apply-actions is an optional instruction in OF 1.3.
90
91 //OFInstruction writeActions =
92 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -070093
94 long cookie = flowRule().id().value();
95
96 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
97 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -080098 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -070099 .setCookie(U64.of(cookie))
100 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700101 .setActions(actions)
102 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700103 .setMatch(match)
104 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
105 .setPriority(flowRule().priority())
106 .build();
107
108 return fm;
109 }
110
111 @Override
112 public OFFlowMod buildFlowMod() {
113 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700114 List<OFAction> actions = buildActions();
115 //OFInstruction writeActions =
116 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700117
118 long cookie = flowRule().id().value();
119
120 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
121 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800122 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700123 .setCookie(U64.of(cookie))
124 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700125 .setActions(actions)
126 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700127 .setMatch(match)
128 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
129 .setPriority(flowRule().priority())
130 .build();
131
132 return fm;
133 }
134
135 @Override
136 public OFFlowDelete buildFlowDel() {
137 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700138 List<OFAction> actions = buildActions();
139 //OFInstruction writeActions =
140 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700141
142 long cookie = flowRule().id().value();
143
144 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800145 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700146 .setCookie(U64.of(cookie))
147 .setBufferId(OFBufferId.NO_BUFFER)
Brian O'Connore4adf242014-11-07 00:16:34 -0800148 //.setActions(actions) //FIXME do we want to send actions in flowdel?
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700149 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700150 .setMatch(match)
151 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
152 .setPriority(flowRule().priority())
153 .build();
154
155 return fm;
156 }
157
158 private List<OFAction> buildActions() {
159 List<OFAction> actions = new LinkedList<>();
160 if (treatment == null) {
161 return actions;
162 }
163 for (Instruction i : treatment.instructions()) {
164 switch (i.type()) {
165 case DROP:
166 log.warn("Saw drop action; assigning drop action");
167 return new LinkedList<>();
168 case L0MODIFICATION:
169 actions.add(buildL0Modification(i));
170 break;
171 case L2MODIFICATION:
172 actions.add(buildL2Modification(i));
173 break;
174 case L3MODIFICATION:
175 actions.add(buildL3Modification(i));
176 break;
177 case OUTPUT:
178 OutputInstruction out = (OutputInstruction) i;
179 actions.add(factory().actions().buildOutput().setPort(
180 OFPort.of((int) out.port().toLong())).build());
181 break;
182 case GROUP:
183 default:
184 log.warn("Instruction type {} not yet implemented.", i.type());
185 }
186 }
187
188 return actions;
189 }
190
191 private OFAction buildL0Modification(Instruction i) {
192 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
193 switch (l0m.subtype()) {
194 case LAMBDA:
195 ModLambdaInstruction ml = (ModLambdaInstruction) i;
196 return factory().actions().circuit(factory().oxms().ochSigidBasic(
197 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
198 default:
199 log.warn("Unimplemented action type {}.", l0m.subtype());
200 break;
201 }
202 return null;
203 }
204
205 private OFAction buildL2Modification(Instruction i) {
206 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
207 ModEtherInstruction eth;
208 OFOxm<?> oxm = null;
209 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800210 case ETH_DST:
211 eth = (ModEtherInstruction) l2m;
212 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
213 break;
214 case ETH_SRC:
215 eth = (ModEtherInstruction) l2m;
216 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
217 break;
218 case VLAN_ID:
219 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
220 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
221 break;
222 case VLAN_PCP:
223 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
224 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
225 break;
226 case MPLS_PUSH:
227 PushHeaderInstructions pushHeaderInstructions =
228 (PushHeaderInstructions) l2m;
229 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
230 .ethernetType().getEtherType()));
231 case MPLS_POP:
232 PushHeaderInstructions popHeaderInstructions =
233 (PushHeaderInstructions) l2m;
234 return factory().actions().popMpls(EthType.of(popHeaderInstructions
235 .ethernetType().getEtherType()));
236 case MPLS_LABEL:
237 ModMplsLabelInstruction mplsLabel =
238 (ModMplsLabelInstruction) l2m;
239 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
240 .longValue()));
241
242 break;
243 default:
244 log.warn("Unimplemented action type {}.", l2m.subtype());
245 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700246 }
247
248 if (oxm != null) {
249 return factory().actions().buildSetField().setField(oxm).build();
250 }
251 return null;
252 }
253
254 private OFAction buildL3Modification(Instruction i) {
255 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
256 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800257 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700258 OFOxm<?> oxm = null;
259 switch (l3m.subtype()) {
260 case IP_DST:
261 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800262 ip4 = ip.ip().getIp4Address();
263 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
Ray Milkey241b96a2014-11-17 13:08:20 -0800264 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700265 case IP_SRC:
266 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800267 ip4 = ip.ip().getIp4Address();
268 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
Ray Milkey241b96a2014-11-17 13:08:20 -0800269 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700270 default:
271 log.warn("Unimplemented action type {}.", l3m.subtype());
272 break;
273 }
274
275 if (oxm != null) {
276 return factory().actions().buildSetField().setField(oxm).build();
277 }
278 return null;
279 }
280
281}