blob: f7cf9a5b40de93cc61e20c9170cc9d50ca556e05 [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;
21
22import org.onlab.onos.net.flow.FlowRule;
23import org.onlab.onos.net.flow.TrafficTreatment;
24import org.onlab.onos.net.flow.instructions.Instruction;
25import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
26import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
27import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
28import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
29import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
30import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
31import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080032import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
33import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
Jonathan Hart86e59352014-10-22 10:42:16 -070034import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
35import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -080036import org.onlab.packet.Ip4Address;
Jonathan Hart86e59352014-10-22 10:42:16 -070037import 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;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080046import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070047import org.projectfloodlight.openflow.types.IPv4Address;
48import org.projectfloodlight.openflow.types.MacAddress;
49import org.projectfloodlight.openflow.types.OFBufferId;
50import org.projectfloodlight.openflow.types.OFPort;
51import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080052import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070053import org.projectfloodlight.openflow.types.U64;
54import org.projectfloodlight.openflow.types.VlanPcp;
55import org.slf4j.Logger;
56import org.slf4j.LoggerFactory;
57
58/**
59 * Flow mod builder for OpenFlow 1.3+.
60 */
61public class FlowModBuilderVer13 extends FlowModBuilder {
62
63 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
64
65 private final TrafficTreatment treatment;
66
67 /**
68 * Constructor for a flow mod builder for OpenFlow 1.3.
69 *
70 * @param flowRule the flow rule to transform into a flow mod
71 * @param factory the OpenFlow factory to use to build the flow mod
72 */
73 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory) {
74 super(flowRule, factory);
75
76 this.treatment = flowRule.treatment();
77 }
78
79 @Override
80 public OFFlowAdd buildFlowAdd() {
81 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070082 List<OFAction> actions = buildActions();
83
84 // FIXME had to revert back to using apply-actions instead of
85 // write-actions because LINC-OE apparently doesn't support
86 // write-actions. I would prefer to change this back in the future
87 // because apply-actions is an optional instruction in OF 1.3.
88
89 //OFInstruction writeActions =
90 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -070091
92 long cookie = flowRule().id().value();
93
94 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
95 OFFlowAdd fm = factory().buildFlowAdd()
96 .setXid(cookie)
97 .setCookie(U64.of(cookie))
98 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070099 .setActions(actions)
100 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700101 .setMatch(match)
102 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
103 .setPriority(flowRule().priority())
104 .build();
105
106 return fm;
107 }
108
109 @Override
110 public OFFlowMod buildFlowMod() {
111 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700112 List<OFAction> actions = buildActions();
113 //OFInstruction writeActions =
114 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700115
116 long cookie = flowRule().id().value();
117
118 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
119 OFFlowMod fm = factory().buildFlowModify()
120 .setXid(cookie)
121 .setCookie(U64.of(cookie))
122 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700123 .setActions(actions)
124 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700125 .setMatch(match)
126 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
127 .setPriority(flowRule().priority())
128 .build();
129
130 return fm;
131 }
132
133 @Override
134 public OFFlowDelete buildFlowDel() {
135 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700136 List<OFAction> actions = buildActions();
137 //OFInstruction writeActions =
138 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700139
140 long cookie = flowRule().id().value();
141
142 OFFlowDelete fm = factory().buildFlowDelete()
143 .setXid(cookie)
144 .setCookie(U64.of(cookie))
145 .setBufferId(OFBufferId.NO_BUFFER)
Brian O'Connore4adf242014-11-07 00:16:34 -0800146 //.setActions(actions) //FIXME do we want to send actions in flowdel?
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700147 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700148 .setMatch(match)
149 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
150 .setPriority(flowRule().priority())
151 .build();
152
153 return fm;
154 }
155
156 private List<OFAction> buildActions() {
157 List<OFAction> actions = new LinkedList<>();
158 if (treatment == null) {
159 return actions;
160 }
161 for (Instruction i : treatment.instructions()) {
162 switch (i.type()) {
163 case DROP:
164 log.warn("Saw drop action; assigning drop action");
165 return new LinkedList<>();
166 case L0MODIFICATION:
167 actions.add(buildL0Modification(i));
168 break;
169 case L2MODIFICATION:
170 actions.add(buildL2Modification(i));
171 break;
172 case L3MODIFICATION:
173 actions.add(buildL3Modification(i));
174 break;
175 case OUTPUT:
176 OutputInstruction out = (OutputInstruction) i;
177 actions.add(factory().actions().buildOutput().setPort(
178 OFPort.of((int) out.port().toLong())).build());
179 break;
180 case GROUP:
181 default:
182 log.warn("Instruction type {} not yet implemented.", i.type());
183 }
184 }
185
186 return actions;
187 }
188
189 private OFAction buildL0Modification(Instruction i) {
190 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
191 switch (l0m.subtype()) {
192 case LAMBDA:
193 ModLambdaInstruction ml = (ModLambdaInstruction) i;
194 return factory().actions().circuit(factory().oxms().ochSigidBasic(
195 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
196 default:
197 log.warn("Unimplemented action type {}.", l0m.subtype());
198 break;
199 }
200 return null;
201 }
202
203 private OFAction buildL2Modification(Instruction i) {
204 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
205 ModEtherInstruction eth;
206 OFOxm<?> oxm = null;
207 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800208 case ETH_DST:
209 eth = (ModEtherInstruction) l2m;
210 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
211 break;
212 case ETH_SRC:
213 eth = (ModEtherInstruction) l2m;
214 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
215 break;
216 case VLAN_ID:
217 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
218 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
219 break;
220 case VLAN_PCP:
221 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
222 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
223 break;
224 case MPLS_PUSH:
225 PushHeaderInstructions pushHeaderInstructions =
226 (PushHeaderInstructions) l2m;
227 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
228 .ethernetType().getEtherType()));
229 case MPLS_POP:
230 PushHeaderInstructions popHeaderInstructions =
231 (PushHeaderInstructions) l2m;
232 return factory().actions().popMpls(EthType.of(popHeaderInstructions
233 .ethernetType().getEtherType()));
234 case MPLS_LABEL:
235 ModMplsLabelInstruction mplsLabel =
236 (ModMplsLabelInstruction) l2m;
237 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
238 .longValue()));
239
240 break;
241 default:
242 log.warn("Unimplemented action type {}.", l2m.subtype());
243 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700244 }
245
246 if (oxm != null) {
247 return factory().actions().buildSetField().setField(oxm).build();
248 }
249 return null;
250 }
251
252 private OFAction buildL3Modification(Instruction i) {
253 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
254 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800255 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700256 OFOxm<?> oxm = null;
257 switch (l3m.subtype()) {
258 case IP_DST:
259 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800260 ip4 = ip.ip().getIp4Address();
261 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700262 case IP_SRC:
263 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800264 ip4 = ip.ip().getIp4Address();
265 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
Jonathan Hart86e59352014-10-22 10:42:16 -0700266 default:
267 log.warn("Unimplemented action type {}.", l3m.subtype());
268 break;
269 }
270
271 if (oxm != null) {
272 return factory().actions().buildSetField().setField(oxm).build();
273 }
274 return null;
275 }
276
277}