blob: eec63fb0e68659a960b98a90f3a60738fe9efdc3 [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;
sangho8995ac52015-02-04 11:29:03 -080024import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080025import org.onosproject.net.flow.instructions.L0ModificationInstruction;
26import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
27import org.onosproject.net.flow.instructions.L2ModificationInstruction;
28import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080029import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
31import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
33import org.onosproject.net.flow.instructions.L3ModificationInstruction;
34import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Jonathan Hart86e59352014-10-22 10:42:16 -070035import org.projectfloodlight.openflow.protocol.OFFactory;
36import org.projectfloodlight.openflow.protocol.OFFlowAdd;
37import org.projectfloodlight.openflow.protocol.OFFlowDelete;
38import org.projectfloodlight.openflow.protocol.OFFlowMod;
39import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
40import org.projectfloodlight.openflow.protocol.action.OFAction;
sangho8995ac52015-02-04 11:29:03 -080041import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080042import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
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;
sangho8995ac52015-02-04 11:29:03 -080050import org.projectfloodlight.openflow.types.OFGroup;
Jonathan Hart86e59352014-10-22 10:42:16 -070051import 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
Jonathan Hart29afca32015-01-20 18:17:39 -080059import java.util.Collections;
60import java.util.LinkedList;
61import java.util.List;
62import java.util.Optional;
63
Jonathan Hart86e59352014-10-22 10:42:16 -070064/**
65 * Flow mod builder for OpenFlow 1.3+.
66 */
67public class FlowModBuilderVer13 extends FlowModBuilder {
68
69 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
Charles M.C. Chanfe421812015-01-12 18:20:51 +080070 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070071
72 private final TrafficTreatment treatment;
73
74 /**
75 * Constructor for a flow mod builder for OpenFlow 1.3.
76 *
77 * @param flowRule the flow rule to transform into a flow mod
78 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080079 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070080 */
Brian O'Connor427a1762014-11-19 18:40:32 -080081 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
82 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070083
84 this.treatment = flowRule.treatment();
85 }
86
87 @Override
88 public OFFlowAdd buildFlowAdd() {
89 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070090 List<OFAction> actions = buildActions();
91
92 // FIXME had to revert back to using apply-actions instead of
93 // write-actions because LINC-OE apparently doesn't support
94 // write-actions. I would prefer to change this back in the future
95 // because apply-actions is an optional instruction in OF 1.3.
96
97 //OFInstruction writeActions =
98 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -070099
100 long cookie = flowRule().id().value();
101
alshabib4785eec2014-12-04 16:45:45 -0800102
Jonathan Hart86e59352014-10-22 10:42:16 -0700103 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800104 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700105 .setCookie(U64.of(cookie))
106 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700107 .setActions(actions)
108 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700109 .setMatch(match)
110 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
111 .setPriority(flowRule().priority())
112 .build();
113
114 return fm;
115 }
116
117 @Override
118 public OFFlowMod buildFlowMod() {
119 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700120 List<OFAction> actions = buildActions();
121 //OFInstruction writeActions =
122 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700123
124 long cookie = flowRule().id().value();
125
alshabib4785eec2014-12-04 16:45:45 -0800126
Jonathan Hart86e59352014-10-22 10:42:16 -0700127 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800128 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700129 .setCookie(U64.of(cookie))
130 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700131 .setActions(actions)
132 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700133 .setMatch(match)
134 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
135 .setPriority(flowRule().priority())
136 .build();
137
138 return fm;
139 }
140
141 @Override
142 public OFFlowDelete buildFlowDel() {
143 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700144 List<OFAction> actions = buildActions();
Jonathan Hart86e59352014-10-22 10:42:16 -0700145
146 long cookie = flowRule().id().value();
147
148 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800149 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700150 .setCookie(U64.of(cookie))
151 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700152 .setMatch(match)
153 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
154 .setPriority(flowRule().priority())
155 .build();
156
157 return fm;
158 }
159
160 private List<OFAction> buildActions() {
161 List<OFAction> actions = new LinkedList<>();
162 if (treatment == null) {
163 return actions;
164 }
165 for (Instruction i : treatment.instructions()) {
166 switch (i.type()) {
167 case DROP:
168 log.warn("Saw drop action; assigning drop action");
169 return new LinkedList<>();
170 case L0MODIFICATION:
171 actions.add(buildL0Modification(i));
172 break;
173 case L2MODIFICATION:
174 actions.add(buildL2Modification(i));
175 break;
176 case L3MODIFICATION:
177 actions.add(buildL3Modification(i));
178 break;
179 case OUTPUT:
180 OutputInstruction out = (OutputInstruction) i;
Charles M.C. Chanfe421812015-01-12 18:20:51 +0800181 OFActionOutput.Builder action = factory().actions().buildOutput()
182 .setPort(OFPort.of((int) out.port().toLong()));
183 if (out.port().equals(PortNumber.CONTROLLER)) {
184 action.setMaxLen(OFPCML_NO_BUFFER);
185 }
186 actions.add(action.build());
Jonathan Hart86e59352014-10-22 10:42:16 -0700187 break;
188 case GROUP:
sangho8995ac52015-02-04 11:29:03 -0800189 GroupInstruction group = (GroupInstruction) i;
190 OFActionGroup.Builder groupBuilder = factory().actions().buildGroup()
191 .setGroup(OFGroup.of(group.groupId().id()));
192 actions.add(groupBuilder.build());
193 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700194 default:
195 log.warn("Instruction type {} not yet implemented.", i.type());
196 }
197 }
198
199 return actions;
200 }
201
202 private OFAction buildL0Modification(Instruction i) {
203 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
204 switch (l0m.subtype()) {
205 case LAMBDA:
206 ModLambdaInstruction ml = (ModLambdaInstruction) i;
207 return factory().actions().circuit(factory().oxms().ochSigidBasic(
208 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
209 default:
210 log.warn("Unimplemented action type {}.", l0m.subtype());
211 break;
212 }
213 return null;
214 }
215
216 private OFAction buildL2Modification(Instruction i) {
217 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
218 ModEtherInstruction eth;
219 OFOxm<?> oxm = null;
220 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800221 case ETH_DST:
222 eth = (ModEtherInstruction) l2m;
223 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
224 break;
225 case ETH_SRC:
226 eth = (ModEtherInstruction) l2m;
227 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
228 break;
229 case VLAN_ID:
230 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
231 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
232 break;
233 case VLAN_PCP:
234 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
235 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
236 break;
237 case MPLS_PUSH:
238 PushHeaderInstructions pushHeaderInstructions =
239 (PushHeaderInstructions) l2m;
240 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
241 .ethernetType().getEtherType()));
242 case MPLS_POP:
243 PushHeaderInstructions popHeaderInstructions =
244 (PushHeaderInstructions) l2m;
245 return factory().actions().popMpls(EthType.of(popHeaderInstructions
246 .ethernetType().getEtherType()));
247 case MPLS_LABEL:
248 ModMplsLabelInstruction mplsLabel =
249 (ModMplsLabelInstruction) l2m;
250 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
251 .longValue()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800252 break;
sangho3f97a17d2015-01-29 22:56:29 -0800253 case DEC_MPLS_TTL:
254 return factory().actions().decMplsTtl();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800255 default:
256 log.warn("Unimplemented action type {}.", l2m.subtype());
257 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700258 }
259
260 if (oxm != null) {
261 return factory().actions().buildSetField().setField(oxm).build();
262 }
263 return null;
264 }
265
266 private OFAction buildL3Modification(Instruction i) {
267 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
268 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800269 Ip4Address ip4;
Jonathan Hart86e59352014-10-22 10:42:16 -0700270 OFOxm<?> oxm = null;
271 switch (l3m.subtype()) {
272 case IP_DST:
273 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800274 ip4 = ip.ip().getIp4Address();
275 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
Ray Milkey241b96a2014-11-17 13:08:20 -0800276 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700277 case IP_SRC:
278 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800279 ip4 = ip.ip().getIp4Address();
280 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
Ray Milkey241b96a2014-11-17 13:08:20 -0800281 break;
sangho3f97a17d2015-01-29 22:56:29 -0800282 case DEC_TTL:
283 return factory().actions().decNwTtl();
284 case TTL_IN:
285 return factory().actions().copyTtlIn();
286 case TTL_OUT:
287 return factory().actions().copyTtlOut();
Jonathan Hart86e59352014-10-22 10:42:16 -0700288 default:
289 log.warn("Unimplemented action type {}.", l3m.subtype());
290 break;
291 }
292
293 if (oxm != null) {
294 return factory().actions().buildSetField().setField(oxm).build();
295 }
296 return null;
297 }
298
299}