blob: fa8035e1ca5bbc1888fd2e691695b692e4a443ae [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;
32import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
33import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
34import 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;
Jonathan Hart86e59352014-10-22 10:42:16 -070040import org.projectfloodlight.openflow.protocol.match.Match;
41import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
42import org.projectfloodlight.openflow.types.CircuitSignalID;
43import org.projectfloodlight.openflow.types.IPv4Address;
44import org.projectfloodlight.openflow.types.MacAddress;
45import org.projectfloodlight.openflow.types.OFBufferId;
46import org.projectfloodlight.openflow.types.OFPort;
47import org.projectfloodlight.openflow.types.OFVlanVidMatch;
48import org.projectfloodlight.openflow.types.U64;
49import org.projectfloodlight.openflow.types.VlanPcp;
50import org.slf4j.Logger;
51import org.slf4j.LoggerFactory;
52
53/**
54 * Flow mod builder for OpenFlow 1.3+.
55 */
56public class FlowModBuilderVer13 extends FlowModBuilder {
57
58 private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class);
59
60 private final TrafficTreatment treatment;
61
62 /**
63 * Constructor for a flow mod builder for OpenFlow 1.3.
64 *
65 * @param flowRule the flow rule to transform into a flow mod
66 * @param factory the OpenFlow factory to use to build the flow mod
67 */
68 protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory) {
69 super(flowRule, factory);
70
71 this.treatment = flowRule.treatment();
72 }
73
74 @Override
75 public OFFlowAdd buildFlowAdd() {
76 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070077 List<OFAction> actions = buildActions();
78
79 // FIXME had to revert back to using apply-actions instead of
80 // write-actions because LINC-OE apparently doesn't support
81 // write-actions. I would prefer to change this back in the future
82 // because apply-actions is an optional instruction in OF 1.3.
83
84 //OFInstruction writeActions =
85 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -070086
87 long cookie = flowRule().id().value();
88
89 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
90 OFFlowAdd fm = factory().buildFlowAdd()
91 .setXid(cookie)
92 .setCookie(U64.of(cookie))
93 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -070094 .setActions(actions)
95 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -070096 .setMatch(match)
97 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
98 .setPriority(flowRule().priority())
99 .build();
100
101 return fm;
102 }
103
104 @Override
105 public OFFlowMod buildFlowMod() {
106 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700107 List<OFAction> actions = buildActions();
108 //OFInstruction writeActions =
109 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700110
111 long cookie = flowRule().id().value();
112
113 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
114 OFFlowMod fm = factory().buildFlowModify()
115 .setXid(cookie)
116 .setCookie(U64.of(cookie))
117 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700118 .setActions(actions)
119 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700120 .setMatch(match)
121 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
122 .setPriority(flowRule().priority())
123 .build();
124
125 return fm;
126 }
127
128 @Override
129 public OFFlowDelete buildFlowDel() {
130 Match match = buildMatch();
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700131 List<OFAction> actions = buildActions();
132 //OFInstruction writeActions =
133 //factory().instructions().writeActions(actions);
Jonathan Hart86e59352014-10-22 10:42:16 -0700134
135 long cookie = flowRule().id().value();
136
137 OFFlowDelete fm = factory().buildFlowDelete()
138 .setXid(cookie)
139 .setCookie(U64.of(cookie))
140 .setBufferId(OFBufferId.NO_BUFFER)
Jonathan Hartd4a8bba2014-10-28 12:44:20 -0700141 .setActions(actions)
142 //.setInstructions(Collections.singletonList(writeActions))
Jonathan Hart86e59352014-10-22 10:42:16 -0700143 .setMatch(match)
144 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
145 .setPriority(flowRule().priority())
146 .build();
147
148 return fm;
149 }
150
151 private List<OFAction> buildActions() {
152 List<OFAction> actions = new LinkedList<>();
153 if (treatment == null) {
154 return actions;
155 }
156 for (Instruction i : treatment.instructions()) {
157 switch (i.type()) {
158 case DROP:
159 log.warn("Saw drop action; assigning drop action");
160 return new LinkedList<>();
161 case L0MODIFICATION:
162 actions.add(buildL0Modification(i));
163 break;
164 case L2MODIFICATION:
165 actions.add(buildL2Modification(i));
166 break;
167 case L3MODIFICATION:
168 actions.add(buildL3Modification(i));
169 break;
170 case OUTPUT:
171 OutputInstruction out = (OutputInstruction) i;
172 actions.add(factory().actions().buildOutput().setPort(
173 OFPort.of((int) out.port().toLong())).build());
174 break;
175 case GROUP:
176 default:
177 log.warn("Instruction type {} not yet implemented.", i.type());
178 }
179 }
180
181 return actions;
182 }
183
184 private OFAction buildL0Modification(Instruction i) {
185 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
186 switch (l0m.subtype()) {
187 case LAMBDA:
188 ModLambdaInstruction ml = (ModLambdaInstruction) i;
189 return factory().actions().circuit(factory().oxms().ochSigidBasic(
190 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
191 default:
192 log.warn("Unimplemented action type {}.", l0m.subtype());
193 break;
194 }
195 return null;
196 }
197
198 private OFAction buildL2Modification(Instruction i) {
199 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
200 ModEtherInstruction eth;
201 OFOxm<?> oxm = null;
202 switch (l2m.subtype()) {
203 case ETH_DST:
204 eth = (ModEtherInstruction) l2m;
205 oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
206 break;
207 case ETH_SRC:
208 eth = (ModEtherInstruction) l2m;
209 oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
210 break;
211 case VLAN_ID:
212 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
213 oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId.toShort()));
214 break;
215 case VLAN_PCP:
216 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
217 oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp));
218 break;
219 default:
220 log.warn("Unimplemented action type {}.", l2m.subtype());
221 break;
222 }
223
224 if (oxm != null) {
225 return factory().actions().buildSetField().setField(oxm).build();
226 }
227 return null;
228 }
229
230 private OFAction buildL3Modification(Instruction i) {
231 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
232 ModIPInstruction ip;
233 OFOxm<?> oxm = null;
234 switch (l3m.subtype()) {
235 case IP_DST:
236 ip = (ModIPInstruction) i;
237 oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip.ip().toInt()));
238 case IP_SRC:
239 ip = (ModIPInstruction) i;
240 oxm = factory().oxms().ipv4Src(IPv4Address.of(ip.ip().toInt()));
241 default:
242 log.warn("Unimplemented action type {}.", l3m.subtype());
243 break;
244 }
245
246 if (oxm != null) {
247 return factory().actions().buildSetField().setField(oxm).build();
248 }
249 return null;
250 }
251
252}