blob: 78f58748dc7c19ae099bdbccfddd007efef7464a [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;
18import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
19import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
20import org.onlab.onos.net.flow.criteria.Criterion;
21import org.onlab.onos.net.flow.instructions.Instruction;
22import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
23import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
24import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
25import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
26import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
27import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
28import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
29import org.projectfloodlight.openflow.protocol.OFFactory;
30import org.projectfloodlight.openflow.protocol.OFFlowMod;
31import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
32import org.projectfloodlight.openflow.protocol.action.OFAction;
33import org.projectfloodlight.openflow.protocol.match.Match;
34import org.projectfloodlight.openflow.protocol.match.MatchField;
35import org.projectfloodlight.openflow.types.EthType;
36import org.projectfloodlight.openflow.types.IPv4Address;
37import org.projectfloodlight.openflow.types.IpProtocol;
38import org.projectfloodlight.openflow.types.MacAddress;
39import org.projectfloodlight.openflow.types.Masked;
40import org.projectfloodlight.openflow.types.OFBufferId;
41import org.projectfloodlight.openflow.types.OFPort;
42import org.projectfloodlight.openflow.types.OFVlanVidMatch;
alshabib6b5cfec2014-09-18 17:42:18 -070043import org.projectfloodlight.openflow.types.U64;
alshabibeec3a062014-09-17 18:01:26 -070044import org.projectfloodlight.openflow.types.VlanPcp;
45import org.projectfloodlight.openflow.types.VlanVid;
46import org.slf4j.Logger;
47
48
49public class FlowModBuilder {
50
51 private final Logger log = getLogger(getClass());
52
53 private final OFFactory factory;
54 private final TrafficTreatment treatment;
55 private final TrafficSelector selector;
56
57 private final int priority;
58
alshabib6b5cfec2014-09-18 17:42:18 -070059 private final FlowId cookie;
60
alshabibeec3a062014-09-17 18:01:26 -070061
62
63 public FlowModBuilder(FlowRule flowRule, OFFactory factory) {
64 this.factory = factory;
65 this.treatment = flowRule.treatment();
66 this.selector = flowRule.selector();
67 this.priority = flowRule.priority();
alshabib6b5cfec2014-09-18 17:42:18 -070068 this.cookie = flowRule.id();
alshabibeec3a062014-09-17 18:01:26 -070069 }
70
alshabib902d41b2014-10-07 16:52:05 -070071 public OFFlowMod buildFlowAdd() {
alshabibeec3a062014-09-17 18:01:26 -070072 Match match = buildMatch();
73 List<OFAction> actions = buildActions();
74
75 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
alshabib6eb438a2014-10-01 16:39:37 -070076 OFFlowMod fm = factory.buildFlowAdd()
alshabib6b5cfec2014-09-18 17:42:18 -070077 .setCookie(U64.of(cookie.value()))
alshabibeec3a062014-09-17 18:01:26 -070078 .setBufferId(OFBufferId.NO_BUFFER)
79 .setActions(actions)
80 .setMatch(match)
81 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
alshabibeec3a062014-09-17 18:01:26 -070082 .setPriority(priority)
83 .build();
84
85 return fm;
86
87 }
88
alshabib902d41b2014-10-07 16:52:05 -070089 public OFFlowMod buildFlowMod() {
90 Match match = buildMatch();
91 List<OFAction> actions = buildActions();
92
93 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
94 OFFlowMod fm = factory.buildFlowModify()
95 .setCookie(U64.of(cookie.value()))
96 .setBufferId(OFBufferId.NO_BUFFER)
97 .setActions(actions)
98 .setMatch(match)
99 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
100 .setPriority(priority)
101 .build();
102
103 return fm;
104
105 }
106
alshabib219ebaa2014-09-22 15:41:24 -0700107 public OFFlowMod buildFlowDel() {
108 Match match = buildMatch();
109 List<OFAction> actions = buildActions();
110
111 OFFlowMod fm = factory.buildFlowDelete()
112 .setCookie(U64.of(cookie.value()))
113 .setBufferId(OFBufferId.NO_BUFFER)
alshabib7814e9f2014-09-30 11:52:12 -0700114 .setActions(actions)
alshabib219ebaa2014-09-22 15:41:24 -0700115 .setMatch(match)
116 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
alshabib219ebaa2014-09-22 15:41:24 -0700117 .setPriority(priority)
118 .build();
119
120 return fm;
121 }
122
alshabibeec3a062014-09-17 18:01:26 -0700123 private List<OFAction> buildActions() {
124 List<OFAction> acts = new LinkedList<>();
alshabib4906fab2014-09-29 23:58:12 -0700125 if (treatment == null) {
126 return acts;
127 }
alshabibeec3a062014-09-17 18:01:26 -0700128 for (Instruction i : treatment.instructions()) {
129 switch (i.type()) {
130 case DROP:
131 log.warn("Saw drop action; assigning drop action");
132 return new LinkedList<>();
133 case L2MODIFICATION:
134 acts.add(buildL2Modification(i));
alshabibf410eee2014-09-22 18:17:45 -0700135 break;
alshabibeec3a062014-09-17 18:01:26 -0700136 case L3MODIFICATION:
137 acts.add(buildL3Modification(i));
alshabibf410eee2014-09-22 18:17:45 -0700138 break;
alshabibeec3a062014-09-17 18:01:26 -0700139 case OUTPUT:
140 OutputInstruction out = (OutputInstruction) i;
141 acts.add(factory.actions().buildOutput().setPort(
142 OFPort.of((int) out.port().toLong())).build());
143 break;
144 case GROUP:
145 default:
146 log.warn("Instruction type {} not yet implemented.", i.type());
147 }
148 }
149
150 return acts;
151 }
152
153 private OFAction buildL3Modification(Instruction i) {
154 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
155 ModIPInstruction ip;
156 switch (l3m.subtype()) {
alshabib99b8fdc2014-09-25 14:30:22 -0700157 case IP_DST:
alshabibeec3a062014-09-17 18:01:26 -0700158 ip = (ModIPInstruction) i;
159 return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
alshabib99b8fdc2014-09-25 14:30:22 -0700160 case IP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700161 ip = (ModIPInstruction) i;
162 return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
163 default:
164 log.warn("Unimplemented action type {}.", l3m.subtype());
165 break;
166 }
167 return null;
168 }
169
170 private OFAction buildL2Modification(Instruction i) {
171 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
172 ModEtherInstruction eth;
173 switch (l2m.subtype()) {
alshabib99b8fdc2014-09-25 14:30:22 -0700174 case ETH_DST:
alshabibeec3a062014-09-17 18:01:26 -0700175 eth = (ModEtherInstruction) l2m;
176 return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
alshabib99b8fdc2014-09-25 14:30:22 -0700177 case ETH_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700178 eth = (ModEtherInstruction) l2m;
179 return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
180 case VLAN_ID:
181 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
182 return factory.actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
183 case VLAN_PCP:
184 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
185 return factory.actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
186 default:
187 log.warn("Unimplemented action type {}.", l2m.subtype());
188 break;
189 }
190 return null;
191 }
192
193 private Match buildMatch() {
194 Match.Builder mBuilder = factory.buildMatch();
195 EthCriterion eth;
196 IPCriterion ip;
197 for (Criterion c : selector.criteria()) {
198 switch (c.type()) {
199 case IN_PORT:
200 PortCriterion inport = (PortCriterion) c;
201 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
202 break;
203 case ETH_SRC:
204 eth = (EthCriterion) c;
205 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
206 break;
207 case ETH_DST:
208 eth = (EthCriterion) c;
209 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
210 break;
211 case ETH_TYPE:
212 EthTypeCriterion ethType = (EthTypeCriterion) c;
213 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
214 break;
215 case IPV4_DST:
216 ip = (IPCriterion) c;
217 if (ip.ip().isMasked()) {
218 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
219 IPv4Address.of(ip.ip().netmask().toInt()));
220 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
221 } else {
222 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
223 }
224 break;
225 case IPV4_SRC:
226 ip = (IPCriterion) c;
227 if (ip.ip().isMasked()) {
228 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
229 IPv4Address.of(ip.ip().netmask().toInt()));
230 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
231 } else {
232 mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
233 }
234 break;
235 case IP_PROTO:
236 IPProtocolCriterion p = (IPProtocolCriterion) c;
237 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
238 break;
239 case VLAN_PCP:
240 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
241 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
242 break;
243 case VLAN_VID:
244 VlanIdCriterion vid = (VlanIdCriterion) c;
245 mBuilder.setExact(MatchField.VLAN_VID,
246 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
247 break;
248 case ARP_OP:
249 case ARP_SHA:
250 case ARP_SPA:
251 case ARP_THA:
252 case ARP_TPA:
253 case ICMPV4_CODE:
254 case ICMPV4_TYPE:
255 case ICMPV6_CODE:
256 case ICMPV6_TYPE:
257 case IN_PHY_PORT:
258 case IPV6_DST:
259 case IPV6_EXTHDR:
260 case IPV6_FLABEL:
261 case IPV6_ND_SLL:
262 case IPV6_ND_TARGET:
263 case IPV6_ND_TLL:
264 case IPV6_SRC:
265 case IP_DSCP:
266 case IP_ECN:
267 case METADATA:
268 case MPLS_BOS:
269 case MPLS_LABEL:
270 case MPLS_TC:
271 case PBB_ISID:
272 case SCTP_DST:
273 case SCTP_SRC:
274 case TCP_DST:
275 case TCP_SRC:
276 case TUNNEL_ID:
277 case UDP_DST:
278 case UDP_SRC:
279 default:
280 log.warn("Match type {} not yet implemented.", c.type());
281 }
282 }
283 return mBuilder.build();
284 }
285
alshabib219ebaa2014-09-22 15:41:24 -0700286
287
alshabibeec3a062014-09-17 18:01:26 -0700288}