blob: e1fde8aa440f03af8fc4c32a2c38c8b0ef79443d [file] [log] [blame]
alshabibeec3a062014-09-17 18:01:26 -07001package org.onlab.onos.provider.of.flow.impl;
2
3import static org.slf4j.LoggerFactory.getLogger;
4
5import java.util.Collections;
6import java.util.LinkedList;
7import java.util.List;
8
alshabib6b5cfec2014-09-18 17:42:18 -07009import org.onlab.onos.net.flow.FlowId;
alshabibeec3a062014-09-17 18:01:26 -070010import org.onlab.onos.net.flow.FlowRule;
11import org.onlab.onos.net.flow.TrafficSelector;
12import org.onlab.onos.net.flow.TrafficTreatment;
13import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
14import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
15import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
16import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
Marc De Leenheer49087752014-10-23 13:54:09 -070017import org.onlab.onos.net.flow.criteria.Criteria.LambdaCriterion;
alshabibeec3a062014-09-17 18:01:26 -070018import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
Jonathan Hart34bc6142014-10-17 11:00:43 -070019import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
alshabibeec3a062014-09-17 18:01:26 -070020import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
21import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
22import org.onlab.onos.net.flow.criteria.Criterion;
23import org.onlab.onos.net.flow.instructions.Instruction;
24import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
Marc De Leenheer49087752014-10-23 13:54:09 -070025import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
26import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
alshabibeec3a062014-09-17 18:01:26 -070027import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
28import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
29import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
30import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
31import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
32import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
33import org.projectfloodlight.openflow.protocol.OFFactory;
alshabib193525b2014-10-08 18:58:03 -070034import org.projectfloodlight.openflow.protocol.OFFlowAdd;
35import org.projectfloodlight.openflow.protocol.OFFlowDelete;
alshabibeec3a062014-09-17 18:01:26 -070036import org.projectfloodlight.openflow.protocol.OFFlowMod;
37import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
38import org.projectfloodlight.openflow.protocol.action.OFAction;
39import org.projectfloodlight.openflow.protocol.match.Match;
40import org.projectfloodlight.openflow.protocol.match.MatchField;
Marc De Leenheer49087752014-10-23 13:54:09 -070041import org.projectfloodlight.openflow.types.CircuitSignalID;
alshabibeec3a062014-09-17 18:01:26 -070042import org.projectfloodlight.openflow.types.EthType;
43import org.projectfloodlight.openflow.types.IPv4Address;
44import org.projectfloodlight.openflow.types.IpProtocol;
45import org.projectfloodlight.openflow.types.MacAddress;
46import org.projectfloodlight.openflow.types.Masked;
47import org.projectfloodlight.openflow.types.OFBufferId;
48import org.projectfloodlight.openflow.types.OFPort;
49import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Jonathan Hart34bc6142014-10-17 11:00:43 -070050import org.projectfloodlight.openflow.types.TransportPort;
alshabib6b5cfec2014-09-18 17:42:18 -070051import org.projectfloodlight.openflow.types.U64;
alshabibeec3a062014-09-17 18:01:26 -070052import org.projectfloodlight.openflow.types.VlanPcp;
53import org.projectfloodlight.openflow.types.VlanVid;
54import org.slf4j.Logger;
55
56
57public class FlowModBuilder {
58
59 private final Logger log = getLogger(getClass());
60
61 private final OFFactory factory;
62 private final TrafficTreatment treatment;
63 private final TrafficSelector selector;
64
65 private final int priority;
66
alshabib6b5cfec2014-09-18 17:42:18 -070067 private final FlowId cookie;
68
alshabibeec3a062014-09-17 18:01:26 -070069
70
71 public FlowModBuilder(FlowRule flowRule, OFFactory factory) {
72 this.factory = factory;
73 this.treatment = flowRule.treatment();
74 this.selector = flowRule.selector();
75 this.priority = flowRule.priority();
alshabib6b5cfec2014-09-18 17:42:18 -070076 this.cookie = flowRule.id();
alshabibeec3a062014-09-17 18:01:26 -070077 }
78
alshabib193525b2014-10-08 18:58:03 -070079 public OFFlowAdd buildFlowAdd() {
alshabibeec3a062014-09-17 18:01:26 -070080 Match match = buildMatch();
81 List<OFAction> actions = buildActions();
82
83 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
alshabib193525b2014-10-08 18:58:03 -070084 OFFlowAdd fm = factory.buildFlowAdd()
85 .setXid(cookie.value())
alshabib6b5cfec2014-09-18 17:42:18 -070086 .setCookie(U64.of(cookie.value()))
alshabibeec3a062014-09-17 18:01:26 -070087 .setBufferId(OFBufferId.NO_BUFFER)
88 .setActions(actions)
89 .setMatch(match)
90 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
alshabibeec3a062014-09-17 18:01:26 -070091 .setPriority(priority)
92 .build();
93
94 return fm;
95
96 }
97
alshabib902d41b2014-10-07 16:52:05 -070098 public OFFlowMod buildFlowMod() {
99 Match match = buildMatch();
100 List<OFAction> actions = buildActions();
101
102 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
103 OFFlowMod fm = factory.buildFlowModify()
alshabib193525b2014-10-08 18:58:03 -0700104 .setXid(cookie.value())
alshabib902d41b2014-10-07 16:52:05 -0700105 .setCookie(U64.of(cookie.value()))
106 .setBufferId(OFBufferId.NO_BUFFER)
107 .setActions(actions)
108 .setMatch(match)
109 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
110 .setPriority(priority)
111 .build();
112
113 return fm;
114
115 }
116
alshabib193525b2014-10-08 18:58:03 -0700117 public OFFlowDelete buildFlowDel() {
alshabib219ebaa2014-09-22 15:41:24 -0700118 Match match = buildMatch();
119 List<OFAction> actions = buildActions();
120
alshabib193525b2014-10-08 18:58:03 -0700121 OFFlowDelete fm = factory.buildFlowDelete()
122 .setXid(cookie.value())
alshabib219ebaa2014-09-22 15:41:24 -0700123 .setCookie(U64.of(cookie.value()))
124 .setBufferId(OFBufferId.NO_BUFFER)
alshabib7814e9f2014-09-30 11:52:12 -0700125 .setActions(actions)
alshabib219ebaa2014-09-22 15:41:24 -0700126 .setMatch(match)
127 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
alshabib219ebaa2014-09-22 15:41:24 -0700128 .setPriority(priority)
129 .build();
130
131 return fm;
132 }
133
alshabibeec3a062014-09-17 18:01:26 -0700134 private List<OFAction> buildActions() {
135 List<OFAction> acts = new LinkedList<>();
alshabib4906fab2014-09-29 23:58:12 -0700136 if (treatment == null) {
137 return acts;
138 }
alshabibeec3a062014-09-17 18:01:26 -0700139 for (Instruction i : treatment.instructions()) {
140 switch (i.type()) {
141 case DROP:
142 log.warn("Saw drop action; assigning drop action");
143 return new LinkedList<>();
Marc De Leenheer49087752014-10-23 13:54:09 -0700144 case L0MODIFICATION:
145 acts.add(buildL0Modification(i));
Marc De Leenheer9eb47ec2014-10-23 14:15:49 -0700146 break;
alshabibeec3a062014-09-17 18:01:26 -0700147 case L2MODIFICATION:
148 acts.add(buildL2Modification(i));
alshabibf410eee2014-09-22 18:17:45 -0700149 break;
alshabibeec3a062014-09-17 18:01:26 -0700150 case L3MODIFICATION:
151 acts.add(buildL3Modification(i));
alshabibf410eee2014-09-22 18:17:45 -0700152 break;
alshabibeec3a062014-09-17 18:01:26 -0700153 case OUTPUT:
154 OutputInstruction out = (OutputInstruction) i;
155 acts.add(factory.actions().buildOutput().setPort(
156 OFPort.of((int) out.port().toLong())).build());
157 break;
158 case GROUP:
159 default:
160 log.warn("Instruction type {} not yet implemented.", i.type());
161 }
162 }
163
164 return acts;
165 }
166
Marc De Leenheer49087752014-10-23 13:54:09 -0700167 private OFAction buildL0Modification(Instruction i) {
168 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
169 switch (l0m.subtype()) {
170 case LAMBDA:
171 ModLambdaInstruction ml = (ModLambdaInstruction) i;
172 return factory.actions().circuit(factory.oxms().ochSigidBasic(
173 new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
174 default:
175 log.warn("Unimplemented action type {}.", l0m.subtype());
176 break;
177 }
178 return null;
179 }
180
alshabibeec3a062014-09-17 18:01:26 -0700181 private OFAction buildL3Modification(Instruction i) {
182 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
183 ModIPInstruction ip;
184 switch (l3m.subtype()) {
alshabib99b8fdc2014-09-25 14:30:22 -0700185 case IP_DST:
alshabibeec3a062014-09-17 18:01:26 -0700186 ip = (ModIPInstruction) i;
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700187 return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
alshabib99b8fdc2014-09-25 14:30:22 -0700188 case IP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700189 ip = (ModIPInstruction) i;
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700190 return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700191 default:
192 log.warn("Unimplemented action type {}.", l3m.subtype());
193 break;
194 }
195 return null;
196 }
197
198 private OFAction buildL2Modification(Instruction i) {
199 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
200 ModEtherInstruction eth;
201 switch (l2m.subtype()) {
alshabib99b8fdc2014-09-25 14:30:22 -0700202 case ETH_DST:
alshabibeec3a062014-09-17 18:01:26 -0700203 eth = (ModEtherInstruction) l2m;
204 return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
alshabib99b8fdc2014-09-25 14:30:22 -0700205 case ETH_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700206 eth = (ModEtherInstruction) l2m;
207 return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
208 case VLAN_ID:
209 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
210 return factory.actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
211 case VLAN_PCP:
212 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
213 return factory.actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
214 default:
215 log.warn("Unimplemented action type {}.", l2m.subtype());
216 break;
217 }
218 return null;
219 }
220
221 private Match buildMatch() {
222 Match.Builder mBuilder = factory.buildMatch();
223 EthCriterion eth;
224 IPCriterion ip;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700225 TcpPortCriterion tp;
alshabibeec3a062014-09-17 18:01:26 -0700226 for (Criterion c : selector.criteria()) {
227 switch (c.type()) {
228 case IN_PORT:
229 PortCriterion inport = (PortCriterion) c;
230 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
231 break;
232 case ETH_SRC:
233 eth = (EthCriterion) c;
234 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
235 break;
236 case ETH_DST:
237 eth = (EthCriterion) c;
238 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
239 break;
240 case ETH_TYPE:
241 EthTypeCriterion ethType = (EthTypeCriterion) c;
242 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
243 break;
244 case IPV4_DST:
245 ip = (IPCriterion) c;
246 if (ip.ip().isMasked()) {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700247 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
248 IPv4Address.of(ip.ip().netmask().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700249 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
250 } else {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700251 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700252 }
253 break;
254 case IPV4_SRC:
255 ip = (IPCriterion) c;
256 if (ip.ip().isMasked()) {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700257 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
258 IPv4Address.of(ip.ip().netmask().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700259 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
260 } else {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700261 mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700262 }
263 break;
264 case IP_PROTO:
265 IPProtocolCriterion p = (IPProtocolCriterion) c;
266 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
267 break;
268 case VLAN_PCP:
269 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
270 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
271 break;
272 case VLAN_VID:
273 VlanIdCriterion vid = (VlanIdCriterion) c;
274 mBuilder.setExact(MatchField.VLAN_VID,
275 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
276 break;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700277 case TCP_DST:
278 tp = (TcpPortCriterion) c;
279 mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
280 break;
281 case TCP_SRC:
282 tp = (TcpPortCriterion) c;
283 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
284 break;
Marc De Leenheer49087752014-10-23 13:54:09 -0700285 case OCH_SIGID:
286 LambdaCriterion lc = (LambdaCriterion) c;
287 mBuilder.setExact(MatchField.OCH_SIGID,
288 new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
289 break;
alshabibeec3a062014-09-17 18:01:26 -0700290 case ARP_OP:
291 case ARP_SHA:
292 case ARP_SPA:
293 case ARP_THA:
294 case ARP_TPA:
295 case ICMPV4_CODE:
296 case ICMPV4_TYPE:
297 case ICMPV6_CODE:
298 case ICMPV6_TYPE:
299 case IN_PHY_PORT:
300 case IPV6_DST:
301 case IPV6_EXTHDR:
302 case IPV6_FLABEL:
303 case IPV6_ND_SLL:
304 case IPV6_ND_TARGET:
305 case IPV6_ND_TLL:
306 case IPV6_SRC:
307 case IP_DSCP:
308 case IP_ECN:
309 case METADATA:
310 case MPLS_BOS:
311 case MPLS_LABEL:
312 case MPLS_TC:
313 case PBB_ISID:
314 case SCTP_DST:
315 case SCTP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700316 case TUNNEL_ID:
317 case UDP_DST:
318 case UDP_SRC:
319 default:
320 log.warn("Match type {} not yet implemented.", c.type());
321 }
322 }
323 return mBuilder.build();
324 }
325
alshabib219ebaa2014-09-22 15:41:24 -0700326
327
alshabibeec3a062014-09-17 18:01:26 -0700328}