blob: 88ec84534bb7a3b24ea8803930aaa91ff3fc3e63 [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;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080019import org.onlab.packet.Ip6Address;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080020import org.onosproject.net.PortNumber;
Brian O'Connorabafb502014-12-02 22:26:20 -080021import org.onosproject.net.flow.FlowRule;
22import org.onosproject.net.flow.TrafficTreatment;
23import org.onosproject.net.flow.instructions.Instruction;
24import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
sangho8995ac52015-02-04 11:29:03 -080025import org.onosproject.net.flow.instructions.Instructions.GroupInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.flow.instructions.L0ModificationInstruction;
27import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
28import org.onosproject.net.flow.instructions.L2ModificationInstruction;
29import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
Jonathan Hart29afca32015-01-20 18:17:39 -080030import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
32import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
34import org.onosproject.net.flow.instructions.L3ModificationInstruction;
35import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080036import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
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;
sangho8995ac52015-02-04 11:29:03 -080043import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
Charles M.C. Chanfe421812015-01-12 18:20:51 +080044import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
Jonathan Hart86e59352014-10-22 10:42:16 -070045import org.projectfloodlight.openflow.protocol.match.Match;
46import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
47import org.projectfloodlight.openflow.types.CircuitSignalID;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080048import org.projectfloodlight.openflow.types.EthType;
Jonathan Hart86e59352014-10-22 10:42:16 -070049import org.projectfloodlight.openflow.types.IPv4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080050import org.projectfloodlight.openflow.types.IPv6Address;
51import org.projectfloodlight.openflow.types.IPv6FlowLabel;
Jonathan Hart86e59352014-10-22 10:42:16 -070052import org.projectfloodlight.openflow.types.MacAddress;
53import org.projectfloodlight.openflow.types.OFBufferId;
sangho8995ac52015-02-04 11:29:03 -080054import org.projectfloodlight.openflow.types.OFGroup;
Jonathan Hart86e59352014-10-22 10:42:16 -070055import org.projectfloodlight.openflow.types.OFPort;
56import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080057import org.projectfloodlight.openflow.types.U32;
Jonathan Hart86e59352014-10-22 10:42:16 -070058import org.projectfloodlight.openflow.types.U64;
59import org.projectfloodlight.openflow.types.VlanPcp;
60import org.slf4j.Logger;
61import org.slf4j.LoggerFactory;
62
Jonathan Hart29afca32015-01-20 18:17:39 -080063import java.util.Collections;
64import java.util.LinkedList;
65import java.util.List;
66import java.util.Optional;
67
Jonathan Hart86e59352014-10-22 10:42:16 -070068/**
69 * Flow mod builder for OpenFlow 1.3+.
70 */
71public class FlowModBuilderVer13 extends FlowModBuilder {
72
73 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
Charles M.C. Chanfe421812015-01-12 18:20:51 +080074 private static final int OFPCML_NO_BUFFER = 0xffff;
Jonathan Hart86e59352014-10-22 10:42:16 -070075
76 private final TrafficTreatment treatment;
77
78 /**
79 * Constructor for a flow mod builder for OpenFlow 1.3.
80 *
81 * @param flowRule the flow rule to transform into a flow mod
82 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080083 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070084 */
Brian O'Connor427a1762014-11-19 18:40:32 -080085 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
86 super(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070087
88 this.treatment = flowRule.treatment();
89 }
90
91 @Override
92 public OFFlowAdd buildFlowAdd() {
93 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070094 List<OFAction> actions = buildActions();
95
96 // FIXME had to revert back to using apply-actions instead of
97 // write-actions because LINC-OE apparently doesn't support
98 // write-actions. I would prefer to change this back in the future
99 // because apply-actions is an optional instruction in OF 1.3.
100
101 //OFInstruction writeActions =
102 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700103
104 long cookie = flowRule().id().value();
105
alshabib4785eec2014-12-04 16:45:45 -0800106
Jonathan Hart86e59352014-10-22 10:42:16 -0700107 OFFlowAdd fm = factory().buildFlowAdd()
Brian O'Connor427a1762014-11-19 18:40:32 -0800108 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700109 .setCookie(U64.of(cookie))
110 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700111 .setActions(actions)
112 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700113 .setMatch(match)
114 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
115 .setPriority(flowRule().priority())
116 .build();
117
118 return fm;
119 }
120
121 @Override
122 public OFFlowMod buildFlowMod() {
123 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700124 List<OFAction> actions = buildActions();
125 //OFInstruction writeActions =
126 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700127
128 long cookie = flowRule().id().value();
129
alshabib4785eec2014-12-04 16:45:45 -0800130
Jonathan Hart86e59352014-10-22 10:42:16 -0700131 OFFlowMod fm = factory().buildFlowModify()
Brian O'Connor427a1762014-11-19 18:40:32 -0800132 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700133 .setCookie(U64.of(cookie))
134 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700135 .setActions(actions)
136 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700137 .setMatch(match)
138 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
139 .setPriority(flowRule().priority())
140 .build();
141
142 return fm;
143 }
144
145 @Override
146 public OFFlowDelete buildFlowDel() {
147 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700148 List<OFAction> actions = buildActions();
Jonathan Hart86e59352014-10-22 10:42:16 -0700149
150 long cookie = flowRule().id().value();
151
152 OFFlowDelete fm = factory().buildFlowDelete()
Brian O'Connor427a1762014-11-19 18:40:32 -0800153 .setXid(xid)
Jonathan Hart86e59352014-10-22 10:42:16 -0700154 .setCookie(U64.of(cookie))
155 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hart86e59352014-10-22 10:42:16 -0700156 .setMatch(match)
157 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
158 .setPriority(flowRule().priority())
159 .build();
160
161 return fm;
162 }
163
164 private List<OFAction> buildActions() {
165 List<OFAction> actions = new LinkedList<>();
166 if (treatment == null) {
167 return actions;
168 }
169 for (Instruction i : treatment.instructions()) {
170 switch (i.type()) {
171 case DROP:
172 log.warn("Saw drop action; assigning drop action");
173 return new LinkedList<>();
174 case L0MODIFICATION:
175 actions.add(buildL0Modification(i));
176 break;
177 case L2MODIFICATION:
178 actions.add(buildL2Modification(i));
179 break;
180 case L3MODIFICATION:
181 actions.add(buildL3Modification(i));
182 break;
183 case OUTPUT:
184 OutputInstruction out = (OutputInstruction) i;
Charles M.C. Chanfe421812015-01-12 18:20:51 +0800185 OFActionOutput.Builder action = factory().actions().buildOutput()
186 .setPort(OFPort.of((int) out.port().toLong()));
187 if (out.port().equals(PortNumber.CONTROLLER)) {
188 action.setMaxLen(OFPCML_NO_BUFFER);
189 }
190 actions.add(action.build());
Jonathan Hart86e59352014-10-22 10:42:16 -0700191 break;
192 case GROUP:
sangho8995ac52015-02-04 11:29:03 -0800193 GroupInstruction group = (GroupInstruction) i;
194 OFActionGroup.Builder groupBuilder = factory().actions().buildGroup()
195 .setGroup(OFGroup.of(group.groupId().id()));
196 actions.add(groupBuilder.build());
197 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700198 default:
199 log.warn("Instruction type {} not yet implemented.", i.type());
200 }
201 }
202
203 return actions;
204 }
205
206 private OFAction buildL0Modification(Instruction i) {
207 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
208 switch (l0m.subtype()) {
209 case LAMBDA:
210 ModLambdaInstruction ml = (ModLambdaInstruction) i;
211 return factory().actions().circuit(factory().oxms().ochSigidBasic(
212 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
213 default:
214 log.warn("Unimplemented action type {}.", l0m.subtype());
215 break;
216 }
217 return null;
218 }
219
220 private OFAction buildL2Modification(Instruction i) {
221 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
222 ModEtherInstruction eth;
223 OFOxm<?> oxm = null;
224 switch (l2m.subtype()) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800225 case ETH_DST:
226 eth = (ModEtherInstruction) l2m;
227 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
228 break;
229 case ETH_SRC:
230 eth = (ModEtherInstruction) l2m;
231 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
232 break;
233 case VLAN_ID:
234 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
235 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
236 break;
237 case VLAN_PCP:
238 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
239 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
240 break;
241 case MPLS_PUSH:
242 PushHeaderInstructions pushHeaderInstructions =
243 (PushHeaderInstructions) l2m;
244 return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800245 .ethernetType()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800246 case MPLS_POP:
247 PushHeaderInstructions popHeaderInstructions =
248 (PushHeaderInstructions) l2m;
249 return factory().actions().popMpls(EthType.of(popHeaderInstructions
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800250 .ethernetType()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800251 case MPLS_LABEL:
252 ModMplsLabelInstruction mplsLabel =
253 (ModMplsLabelInstruction) l2m;
254 oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
255 .longValue()));
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800256 break;
sangho3f97a17d2015-01-29 22:56:29 -0800257 case DEC_MPLS_TTL:
258 return factory().actions().decMplsTtl();
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800259 default:
260 log.warn("Unimplemented action type {}.", l2m.subtype());
261 break;
Jonathan Hart86e59352014-10-22 10:42:16 -0700262 }
263
264 if (oxm != null) {
265 return factory().actions().buildSetField().setField(oxm).build();
266 }
267 return null;
268 }
269
270 private OFAction buildL3Modification(Instruction i) {
271 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
272 ModIPInstruction ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800273 Ip4Address ip4;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800274 Ip6Address ip6;
Jonathan Hart86e59352014-10-22 10:42:16 -0700275 OFOxm<?> oxm = null;
276 switch (l3m.subtype()) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800277 case IPV4_SRC:
278 ip = (ModIPInstruction) i;
279 ip4 = ip.ip().getIp4Address();
280 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
281 break;
282 case IPV4_DST:
Jonathan Hart86e59352014-10-22 10:42:16 -0700283 ip = (ModIPInstruction) i;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800284 ip4 = ip.ip().getIp4Address();
285 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
Ray Milkey241b96a2014-11-17 13:08:20 -0800286 break;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800287 case IPV6_SRC:
Jonathan Hart86e59352014-10-22 10:42:16 -0700288 ip = (ModIPInstruction) i;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800289 ip6 = ip.ip().getIp6Address();
290 oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
291 break;
292 case IPV6_DST:
293 ip = (ModIPInstruction) i;
294 ip6 = ip.ip().getIp6Address();
295 oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
296 break;
297 case IPV6_FLABEL:
298 ModIPv6FlowLabelInstruction flowLabelInstruction =
299 (ModIPv6FlowLabelInstruction) i;
300 int flowLabel = flowLabelInstruction.flowLabel();
301 oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
Ray Milkey241b96a2014-11-17 13:08:20 -0800302 break;
sangho3f97a17d2015-01-29 22:56:29 -0800303 case DEC_TTL:
304 return factory().actions().decNwTtl();
305 case TTL_IN:
306 return factory().actions().copyTtlIn();
307 case TTL_OUT:
308 return factory().actions().copyTtlOut();
Jonathan Hart86e59352014-10-22 10:42:16 -0700309 default:
310 log.warn("Unimplemented action type {}.", l3m.subtype());
311 break;
312 }
313
314 if (oxm != null) {
315 return factory().actions().buildSetField().setField(oxm).build();
316 }
317 return null;
318 }
319
320}