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