blob: 64ebe0d0d83d068abe90cfbd907fb6d779487fac [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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.of.flow.impl;
Jonathan Hart86e59352014-10-22 10:42:16 -070017
Jonathan Hart29afca32015-01-20 18:17:39 -080018import org.onlab.packet.Ip4Address;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080019import org.onosproject.net.PortNumber;
Brian O'Connorabafb502014-12-02 22:26:20 -080020import org.onosproject.net.flow.FlowRule;
21import org.onosproject.net.flow.TrafficTreatment;
22import org.onosproject.net.flow.instructions.Instruction;
23import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
24import org.onosproject.net.flow.instructions.L0ModificationInstruction;
25import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
26import org.onosproject.net.flow.instructions.L2ModificationInstruction;
27import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080028import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
30import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
32import org.onosproject.net.flow.instructions.L3ModificationInstruction;
33import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070034import org.projectfloodlight.openflow.protocol.OFFactory;
35import org.projectfloodlight.openflow.protocol.OFFlowAdd;
36import org.projectfloodlight.openflow.protocol.OFFlowDelete;
37import org.projectfloodlight.openflow.protocol.OFFlowMod;
38import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
39import org.projectfloodlight.openflow.protocol.action.OFAction;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080040import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Jonathan Hart86e59352014-10-22 10:42:16 -070041import org.projectfloodlight.openflow.protocol.match.Match;
42import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
43import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080044import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070045import org.projectfloodlight.openflow.types.IPv4Address;
46import org.projectfloodlight.openflow.types.MacAddress;
47import org.projectfloodlight.openflow.types.OFBufferId;
48import org.projectfloodlight.openflow.types.OFPort;
49import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080050import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070051import org.projectfloodlight.openflow.types.U64;
52import org.projectfloodlight.openflow.types.VlanPcp;
53import org.slf4j.Logger;
54import org.slf4j.LoggerFactory;
55
Jonathan Hart29afca32015-01-20 18:17:39 -080056import java.util.Collections;
57import java.util.LinkedList;
58import java.util.List;
59import java.util.Optional;
60
Jonathan Hart86e59352014-10-22 10:42:16 -070061/**
62 * Flow mod builder for OpenFlow 1.3+.
63 */
64public class FlowModBuilderVer13 extends FlowModBuilder {
65
66 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
Charles M.C. Chanfe421812015-01-12 18:20:51 +080067 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070068
69 private final TrafficTreatment treatment;
70
71 /**
72 * Constructor for a flow mod builder for OpenFlow 1.3.
73 *
74 * @param flowRule the flow rule to transform into a flow mod
75 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080076 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070077 */
Brian O'Connor427a1762014-11-19 18:40:32 -080078 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
79 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070080
81 this.treatment = flowRule.treatment();
82 }
83
84 @Override
85 public OFFlowAdd buildFlowAdd() {
86 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070087 List<OFAction> actions = buildActions();
88
89 // FIXME had to revert back to using apply-actions instead of
90 // write-actions because LINC-OE apparently doesn't support
91 // write-actions. I would prefer to change this back in the future
92 // because apply-actions is an optional instruction in OF 1.3.
93
94 //OFInstruction writeActions =
95 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -070096
97 long cookie = flowRule().id().value();
98
alshabib4785eec2014-12-04 16:45:45 -080099
Jonathan Hart86e59352014-10-22 10:42:16 -0700100 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800101 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700102 .setCookie(U64.of(cookie))
103 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700104 .setActions(actions)
105 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700106 .setMatch(match)
107 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
108 .setPriority(flowRule().priority())
109 .build();
110
111 return fm;
112 }
113
114 @Override
115 public OFFlowMod buildFlowMod() {
116 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700117 List<OFAction> actions = buildActions();
118 //OFInstruction writeActions =
119 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700120
121 long cookie = flowRule().id().value();
122
alshabib4785eec2014-12-04 16:45:45 -0800123
Jonathan Hart86e59352014-10-22 10:42:16 -0700124 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800125 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700126 .setCookie(U64.of(cookie))
127 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700128 .setActions(actions)
129 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700130 .setMatch(match)
131 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
132 .setPriority(flowRule().priority())
133 .build();
134
135 return fm;
136 }
137
138 @Override
139 public OFFlowDelete buildFlowDel() {
140 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700141 List<OFAction> actions = buildActions();
Jonathan Hart86e59352014-10-22 10:42:16 -0700142
143 long cookie = flowRule().id().value();
144
145 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800146 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700147 .setCookie(U64.of(cookie))
148 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700149 .setMatch(match)
150 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
151 .setPriority(flowRule().priority())
152 .build();
153
154 return fm;
155 }
156
157 private List<OFAction> buildActions() {
158 List<OFAction> actions = new LinkedList<>();
159 if (treatment == null) {
160 return actions;
161 }
162 for (Instruction i : treatment.instructions()) {
163 switch (i.type()) {
164 case DROP:
165 log.warn("Saw drop action; assigning drop action");
166 return new LinkedList<>();
167 case L0MODIFICATION:
168 actions.add(buildL0Modification(i));
169 break;
170 case L2MODIFICATION:
171 actions.add(buildL2Modification(i));
172 break;
173 case L3MODIFICATION:
174 actions.add(buildL3Modification(i));
175 break;
176 case OUTPUT:
177 OutputInstruction out = (OutputInstruction) i;
Charles M.C. Chanfe421812015-01-12 18:20:51 +0800178 OFActionOutput.Builder action = factory().actions().buildOutput()
179 .setPort(OFPort.of((int) out.port().toLong()));
180 if (out.port().equals(PortNumber.CONTROLLER)) {
181 action.setMaxLen(OFPCML_NO_BUFFER);
182 }
183 actions.add(action.build());
Jonathan Hart86e59352014-10-22 10:42:16 -0700184 break;
185 case GROUP:
186 default:
187 log.warn("Instruction type {} not yet implemented.", i.type());
188 }
189 }
190
191 return actions;
192 }
193
194 private OFAction buildL0Modification(Instruction i) {
195 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
196 switch (l0m.subtype()) {
197 case LAMBDA:
198 ModLambdaInstruction ml = (ModLambdaInstruction) i;
199 return factory().actions().circuit(factory().oxms().ochSigidBasic(
200 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
201 default:
202 log.warn("Unimplemented action type {}.", l0m.subtype());
203 break;
204 }
205 return null;
206 }
207
208 private OFAction buildL2Modification(Instruction i) {
209 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
210 ModEtherInstruction eth;
211 OFOxm<?> oxm = null;
212 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800213 case ETH_DST:
214 eth = (ModEtherInstruction) l2m;
215 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
216 break;
217 case ETH_SRC:
218 eth = (ModEtherInstruction) l2m;
219 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
220 break;
221 case VLAN_ID:
222 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
223 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
224 break;
225 case VLAN_PCP:
226 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
227 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
228 break;
229 case MPLS_PUSH:
230 PushHeaderInstructions pushHeaderInstructions =
231 (PushHeaderInstructions) l2m;
232 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
233 .ethernetType().getEtherType()));
234 case MPLS_POP:
235 PushHeaderInstructions popHeaderInstructions =
236 (PushHeaderInstructions) l2m;
237 return factory().actions().popMpls(EthType.of(popHeaderInstructions
238 .ethernetType().getEtherType()));
239 case MPLS_LABEL:
240 ModMplsLabelInstruction mplsLabel =
241 (ModMplsLabelInstruction) l2m;
242 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
243 .longValue()));
244
245 break;
246 default:
247 log.warn("Unimplemented action type {}.", l2m.subtype());
248 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700249 }
250
251 if (oxm != null) {
252 return factory().actions().buildSetField().setField(oxm).build();
253 }
254 return null;
255 }
256
257 private OFAction buildL3Modification(Instruction i) {
258 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
259 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800260 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700261 OFOxm<?> oxm = null;
262 switch (l3m.subtype()) {
263 case IP_DST:
264 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800265 ip4 = ip.ip().getIp4Address();
266 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
Ray Milkey241b96a2014-11-17 13:08:20 -0800267 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700268 case IP_SRC:
269 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800270 ip4 = ip.ip().getIp4Address();
271 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
Ray Milkey241b96a2014-11-17 13:08:20 -0800272 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700273 default:
274 log.warn("Unimplemented action type {}.", l3m.subtype());
275 break;
276 }
277
278 if (oxm != null) {
279 return factory().actions().buildSetField().setField(oxm).build();
280 }
281 return null;
282 }
283
284}