blob: aa508338b05507966276862c33878f36a1f04fcf [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;
17import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
Jonathan Hart34bc6142014-10-17 11:00:43 -070018import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
alshabibeec3a062014-09-17 18:01:26 -070019import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
20import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
21import org.onlab.onos.net.flow.criteria.Criterion;
22import org.onlab.onos.net.flow.instructions.Instruction;
23import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
24import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
25import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
26import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
27import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
28import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
29import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
30import org.projectfloodlight.openflow.protocol.OFFactory;
alshabib193525b2014-10-08 18:58:03 -070031import org.projectfloodlight.openflow.protocol.OFFlowAdd;
32import org.projectfloodlight.openflow.protocol.OFFlowDelete;
alshabibeec3a062014-09-17 18:01:26 -070033import org.projectfloodlight.openflow.protocol.OFFlowMod;
34import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
35import org.projectfloodlight.openflow.protocol.action.OFAction;
36import org.projectfloodlight.openflow.protocol.match.Match;
37import org.projectfloodlight.openflow.protocol.match.MatchField;
38import org.projectfloodlight.openflow.types.EthType;
39import org.projectfloodlight.openflow.types.IPv4Address;
40import org.projectfloodlight.openflow.types.IpProtocol;
41import org.projectfloodlight.openflow.types.MacAddress;
42import org.projectfloodlight.openflow.types.Masked;
43import org.projectfloodlight.openflow.types.OFBufferId;
44import org.projectfloodlight.openflow.types.OFPort;
45import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Jonathan Hart34bc6142014-10-17 11:00:43 -070046import org.projectfloodlight.openflow.types.TransportPort;
alshabib6b5cfec2014-09-18 17:42:18 -070047import org.projectfloodlight.openflow.types.U64;
alshabibeec3a062014-09-17 18:01:26 -070048import org.projectfloodlight.openflow.types.VlanPcp;
49import org.projectfloodlight.openflow.types.VlanVid;
50import org.slf4j.Logger;
51
52
53public class FlowModBuilder {
54
55 private final Logger log = getLogger(getClass());
56
57 private final OFFactory factory;
58 private final TrafficTreatment treatment;
59 private final TrafficSelector selector;
60
61 private final int priority;
62
alshabib6b5cfec2014-09-18 17:42:18 -070063 private final FlowId cookie;
64
alshabibeec3a062014-09-17 18:01:26 -070065
66
67 public FlowModBuilder(FlowRule flowRule, OFFactory factory) {
68 this.factory = factory;
69 this.treatment = flowRule.treatment();
70 this.selector = flowRule.selector();
71 this.priority = flowRule.priority();
alshabib6b5cfec2014-09-18 17:42:18 -070072 this.cookie = flowRule.id();
alshabibeec3a062014-09-17 18:01:26 -070073 }
74
alshabib193525b2014-10-08 18:58:03 -070075 public OFFlowAdd buildFlowAdd() {
alshabibeec3a062014-09-17 18:01:26 -070076 Match match = buildMatch();
77 List<OFAction> actions = buildActions();
78
79 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
alshabib193525b2014-10-08 18:58:03 -070080 OFFlowAdd fm = factory.buildFlowAdd()
81 .setXid(cookie.value())
alshabib6b5cfec2014-09-18 17:42:18 -070082 .setCookie(U64.of(cookie.value()))
alshabibeec3a062014-09-17 18:01:26 -070083 .setBufferId(OFBufferId.NO_BUFFER)
84 .setActions(actions)
85 .setMatch(match)
86 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
alshabibeec3a062014-09-17 18:01:26 -070087 .setPriority(priority)
88 .build();
89
90 return fm;
91
92 }
93
alshabib902d41b2014-10-07 16:52:05 -070094 public OFFlowMod buildFlowMod() {
95 Match match = buildMatch();
96 List<OFAction> actions = buildActions();
97
98 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
99 OFFlowMod fm = factory.buildFlowModify()
alshabib193525b2014-10-08 18:58:03 -0700100 .setXid(cookie.value())
alshabib902d41b2014-10-07 16:52:05 -0700101 .setCookie(U64.of(cookie.value()))
102 .setBufferId(OFBufferId.NO_BUFFER)
103 .setActions(actions)
104 .setMatch(match)
105 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
106 .setPriority(priority)
107 .build();
108
109 return fm;
110
111 }
112
alshabib193525b2014-10-08 18:58:03 -0700113 public OFFlowDelete buildFlowDel() {
alshabib219ebaa2014-09-22 15:41:24 -0700114 Match match = buildMatch();
115 List<OFAction> actions = buildActions();
116
alshabib193525b2014-10-08 18:58:03 -0700117 OFFlowDelete fm = factory.buildFlowDelete()
118 .setXid(cookie.value())
alshabib219ebaa2014-09-22 15:41:24 -0700119 .setCookie(U64.of(cookie.value()))
120 .setBufferId(OFBufferId.NO_BUFFER)
alshabib7814e9f2014-09-30 11:52:12 -0700121 .setActions(actions)
alshabib219ebaa2014-09-22 15:41:24 -0700122 .setMatch(match)
123 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
alshabib219ebaa2014-09-22 15:41:24 -0700124 .setPriority(priority)
125 .build();
126
127 return fm;
128 }
129
alshabibeec3a062014-09-17 18:01:26 -0700130 private List<OFAction> buildActions() {
131 List<OFAction> acts = new LinkedList<>();
alshabib4906fab2014-09-29 23:58:12 -0700132 if (treatment == null) {
133 return acts;
134 }
alshabibeec3a062014-09-17 18:01:26 -0700135 for (Instruction i : treatment.instructions()) {
136 switch (i.type()) {
137 case DROP:
138 log.warn("Saw drop action; assigning drop action");
139 return new LinkedList<>();
140 case L2MODIFICATION:
141 acts.add(buildL2Modification(i));
alshabibf410eee2014-09-22 18:17:45 -0700142 break;
alshabibeec3a062014-09-17 18:01:26 -0700143 case L3MODIFICATION:
144 acts.add(buildL3Modification(i));
alshabibf410eee2014-09-22 18:17:45 -0700145 break;
alshabibeec3a062014-09-17 18:01:26 -0700146 case OUTPUT:
147 OutputInstruction out = (OutputInstruction) i;
148 acts.add(factory.actions().buildOutput().setPort(
149 OFPort.of((int) out.port().toLong())).build());
150 break;
151 case GROUP:
152 default:
153 log.warn("Instruction type {} not yet implemented.", i.type());
154 }
155 }
156
157 return acts;
158 }
159
160 private OFAction buildL3Modification(Instruction i) {
161 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
162 ModIPInstruction ip;
163 switch (l3m.subtype()) {
alshabib99b8fdc2014-09-25 14:30:22 -0700164 case IP_DST:
alshabibeec3a062014-09-17 18:01:26 -0700165 ip = (ModIPInstruction) i;
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700166 return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
alshabib99b8fdc2014-09-25 14:30:22 -0700167 case IP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700168 ip = (ModIPInstruction) i;
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700169 return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700170 default:
171 log.warn("Unimplemented action type {}.", l3m.subtype());
172 break;
173 }
174 return null;
175 }
176
177 private OFAction buildL2Modification(Instruction i) {
178 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
179 ModEtherInstruction eth;
180 switch (l2m.subtype()) {
alshabib99b8fdc2014-09-25 14:30:22 -0700181 case ETH_DST:
alshabibeec3a062014-09-17 18:01:26 -0700182 eth = (ModEtherInstruction) l2m;
183 return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
alshabib99b8fdc2014-09-25 14:30:22 -0700184 case ETH_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700185 eth = (ModEtherInstruction) l2m;
186 return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
187 case VLAN_ID:
188 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
189 return factory.actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
190 case VLAN_PCP:
191 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
192 return factory.actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
193 default:
194 log.warn("Unimplemented action type {}.", l2m.subtype());
195 break;
196 }
197 return null;
198 }
199
200 private Match buildMatch() {
201 Match.Builder mBuilder = factory.buildMatch();
202 EthCriterion eth;
203 IPCriterion ip;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700204 TcpPortCriterion tp;
alshabibeec3a062014-09-17 18:01:26 -0700205 for (Criterion c : selector.criteria()) {
206 switch (c.type()) {
207 case IN_PORT:
208 PortCriterion inport = (PortCriterion) c;
209 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
210 break;
211 case ETH_SRC:
212 eth = (EthCriterion) c;
213 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
214 break;
215 case ETH_DST:
216 eth = (EthCriterion) c;
217 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
218 break;
219 case ETH_TYPE:
220 EthTypeCriterion ethType = (EthTypeCriterion) c;
221 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
222 break;
223 case IPV4_DST:
224 ip = (IPCriterion) c;
225 if (ip.ip().isMasked()) {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700226 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
227 IPv4Address.of(ip.ip().netmask().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700228 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
229 } else {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700230 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700231 }
232 break;
233 case IPV4_SRC:
234 ip = (IPCriterion) c;
235 if (ip.ip().isMasked()) {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700236 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
237 IPv4Address.of(ip.ip().netmask().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700238 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
239 } else {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700240 mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700241 }
242 break;
243 case IP_PROTO:
244 IPProtocolCriterion p = (IPProtocolCriterion) c;
245 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
246 break;
247 case VLAN_PCP:
248 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
249 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
250 break;
251 case VLAN_VID:
252 VlanIdCriterion vid = (VlanIdCriterion) c;
253 mBuilder.setExact(MatchField.VLAN_VID,
254 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
255 break;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700256 case TCP_DST:
257 tp = (TcpPortCriterion) c;
258 mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
259 break;
260 case TCP_SRC:
261 tp = (TcpPortCriterion) c;
262 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
263 break;
alshabibeec3a062014-09-17 18:01:26 -0700264 case ARP_OP:
265 case ARP_SHA:
266 case ARP_SPA:
267 case ARP_THA:
268 case ARP_TPA:
269 case ICMPV4_CODE:
270 case ICMPV4_TYPE:
271 case ICMPV6_CODE:
272 case ICMPV6_TYPE:
273 case IN_PHY_PORT:
274 case IPV6_DST:
275 case IPV6_EXTHDR:
276 case IPV6_FLABEL:
277 case IPV6_ND_SLL:
278 case IPV6_ND_TARGET:
279 case IPV6_ND_TLL:
280 case IPV6_SRC:
281 case IP_DSCP:
282 case IP_ECN:
283 case METADATA:
284 case MPLS_BOS:
285 case MPLS_LABEL:
286 case MPLS_TC:
287 case PBB_ISID:
288 case SCTP_DST:
289 case SCTP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700290 case TUNNEL_ID:
291 case UDP_DST:
292 case UDP_SRC:
293 default:
294 log.warn("Match type {} not yet implemented.", c.type());
295 }
296 }
297 return mBuilder.build();
298 }
299
alshabib219ebaa2014-09-22 15:41:24 -0700300
301
alshabibeec3a062014-09-17 18:01:26 -0700302}