blob: 78efee2b8b0b4e7405e5fba70c4daafa58a2ddf5 [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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.of.flow.impl;
alshabibeec3a062014-09-17 18:01:26 -070017
18import static org.slf4j.LoggerFactory.getLogger;
19
Charles M.C. Chan52fae7d2015-01-17 00:35:53 +080020import org.onlab.packet.Ip6Address;
21import org.onlab.packet.Ip6Prefix;
Brian O'Connorabafb502014-12-02 22:26:20 -080022import org.onosproject.net.flow.FlowRule;
23import org.onosproject.net.flow.TrafficSelector;
24import org.onosproject.net.flow.criteria.Criteria;
25import org.onosproject.net.flow.criteria.Criteria.EthCriterion;
26import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion;
27import org.onosproject.net.flow.criteria.Criteria.IPCriterion;
28import org.onosproject.net.flow.criteria.Criteria.IPProtocolCriterion;
29import org.onosproject.net.flow.criteria.Criteria.LambdaCriterion;
30import org.onosproject.net.flow.criteria.Criteria.PortCriterion;
31import org.onosproject.net.flow.criteria.Criteria.TcpPortCriterion;
32import org.onosproject.net.flow.criteria.Criteria.VlanIdCriterion;
33import org.onosproject.net.flow.criteria.Criteria.VlanPcpCriterion;
Kunihiro Ishiguro0f9aba82015-01-15 17:14:17 -080034import org.onosproject.net.flow.criteria.Criteria.Icmpv6TypeCriterion;
35import org.onosproject.net.flow.criteria.Criteria.Icmpv6CodeCriterion;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.flow.criteria.Criterion;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -080037import org.onlab.packet.Ip4Address;
38import org.onlab.packet.Ip4Prefix;
alshabibeec3a062014-09-17 18:01:26 -070039import org.projectfloodlight.openflow.protocol.OFFactory;
alshabib193525b2014-10-08 18:58:03 -070040import org.projectfloodlight.openflow.protocol.OFFlowAdd;
41import org.projectfloodlight.openflow.protocol.OFFlowDelete;
alshabibeec3a062014-09-17 18:01:26 -070042import org.projectfloodlight.openflow.protocol.OFFlowMod;
alshabibeec3a062014-09-17 18:01:26 -070043import org.projectfloodlight.openflow.protocol.match.Match;
44import org.projectfloodlight.openflow.protocol.match.MatchField;
Marc De Leenheer49087752014-10-23 13:54:09 -070045import org.projectfloodlight.openflow.types.CircuitSignalID;
alshabibeec3a062014-09-17 18:01:26 -070046import org.projectfloodlight.openflow.types.EthType;
47import org.projectfloodlight.openflow.types.IPv4Address;
Charles M.C. Chan52fae7d2015-01-17 00:35:53 +080048import org.projectfloodlight.openflow.types.IPv6Address;
alshabibeec3a062014-09-17 18:01:26 -070049import org.projectfloodlight.openflow.types.IpProtocol;
50import org.projectfloodlight.openflow.types.MacAddress;
51import org.projectfloodlight.openflow.types.Masked;
alshabibeec3a062014-09-17 18:01:26 -070052import org.projectfloodlight.openflow.types.OFPort;
53import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Jonathan Hart34bc6142014-10-17 11:00:43 -070054import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080055import org.projectfloodlight.openflow.types.U32;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -080056import org.projectfloodlight.openflow.types.U8;
alshabibeec3a062014-09-17 18:01:26 -070057import org.projectfloodlight.openflow.types.VlanPcp;
58import org.projectfloodlight.openflow.types.VlanVid;
59import org.slf4j.Logger;
60
Brian O'Connor427a1762014-11-19 18:40:32 -080061import java.util.Optional;
62
Jonathan Hart86e59352014-10-22 10:42:16 -070063/**
64 * Builder for OpenFlow flow mods based on FlowRules.
65 */
66public abstract class FlowModBuilder {
alshabibeec3a062014-09-17 18:01:26 -070067
68 private final Logger log = getLogger(getClass());
69
70 private final OFFactory factory;
Jonathan Hart86e59352014-10-22 10:42:16 -070071 private final FlowRule flowRule;
alshabibeec3a062014-09-17 18:01:26 -070072 private final TrafficSelector selector;
Brian O'Connor427a1762014-11-19 18:40:32 -080073 protected final Long xid;
alshabibeec3a062014-09-17 18:01:26 -070074
Jonathan Hart86e59352014-10-22 10:42:16 -070075 /**
76 * Creates a new flow mod builder.
77 *
78 * @param flowRule the flow rule to transform into a flow mod
79 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080080 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070081 * @return the new flow mod builder
82 */
Brian O'Connor427a1762014-11-19 18:40:32 -080083 public static FlowModBuilder builder(FlowRule flowRule,
84 OFFactory factory, Optional<Long> xid) {
Jonathan Hart86e59352014-10-22 10:42:16 -070085 switch (factory.getVersion()) {
86 case OF_10:
Brian O'Connor427a1762014-11-19 18:40:32 -080087 return new FlowModBuilderVer10(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070088 case OF_13:
Brian O'Connor427a1762014-11-19 18:40:32 -080089 return new FlowModBuilderVer13(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070090 default:
91 throw new UnsupportedOperationException(
92 "No flow mod builder for protocol version " + factory.getVersion());
93 }
94 }
alshabibeec3a062014-09-17 18:01:26 -070095
Jonathan Hart86e59352014-10-22 10:42:16 -070096 /**
97 * Constructs a flow mod builder.
98 *
99 * @param flowRule the flow rule to transform into a flow mod
100 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -0800101 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -0700102 */
Brian O'Connor427a1762014-11-19 18:40:32 -0800103 protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
alshabibeec3a062014-09-17 18:01:26 -0700104 this.factory = factory;
Jonathan Hart86e59352014-10-22 10:42:16 -0700105 this.flowRule = flowRule;
alshabibeec3a062014-09-17 18:01:26 -0700106 this.selector = flowRule.selector();
Brian O'Connor427a1762014-11-19 18:40:32 -0800107 this.xid = xid.orElse((long) 0);
108
alshabibeec3a062014-09-17 18:01:26 -0700109 }
110
Jonathan Hart86e59352014-10-22 10:42:16 -0700111 /**
112 * Builds an ADD flow mod.
113 *
114 * @return the flow mod
115 */
116 public abstract OFFlowAdd buildFlowAdd();
alshabibeec3a062014-09-17 18:01:26 -0700117
Jonathan Hart86e59352014-10-22 10:42:16 -0700118 /**
119 * Builds a MODIFY flow mod.
120 *
121 * @return the flow mod
122 */
123 public abstract OFFlowMod buildFlowMod();
alshabibeec3a062014-09-17 18:01:26 -0700124
Jonathan Hart86e59352014-10-22 10:42:16 -0700125 /**
126 * Builds a DELETE flow mod.
127 *
128 * @return the flow mod
129 */
130 public abstract OFFlowDelete buildFlowDel();
alshabibeec3a062014-09-17 18:01:26 -0700131
Jonathan Hart86e59352014-10-22 10:42:16 -0700132 /**
133 * Builds the match for the flow mod.
134 *
135 * @return the match
136 */
137 protected Match buildMatch() {
alshabibeec3a062014-09-17 18:01:26 -0700138 Match.Builder mBuilder = factory.buildMatch();
139 EthCriterion eth;
140 IPCriterion ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800141 Ip4Prefix ip4Prefix;
Charles M.C. Chan52fae7d2015-01-17 00:35:53 +0800142 Ip6Prefix ip6Prefix;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700143 TcpPortCriterion tp;
alshabibeec3a062014-09-17 18:01:26 -0700144 for (Criterion c : selector.criteria()) {
145 switch (c.type()) {
146 case IN_PORT:
147 PortCriterion inport = (PortCriterion) c;
148 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
149 break;
150 case ETH_SRC:
151 eth = (EthCriterion) c;
152 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
153 break;
154 case ETH_DST:
155 eth = (EthCriterion) c;
156 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
157 break;
158 case ETH_TYPE:
159 EthTypeCriterion ethType = (EthTypeCriterion) c;
160 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
161 break;
162 case IPV4_DST:
163 ip = (IPCriterion) c;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800164 ip4Prefix = ip.ip().getIp4Prefix();
165 if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
166 Ip4Address maskAddr =
167 Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700168 Masked<IPv4Address> maskedIp =
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800169 Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700170 IPv4Address.of(maskAddr.toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700171 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
172 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700173 mBuilder.setExact(MatchField.IPV4_DST,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800174 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700175 }
176 break;
177 case IPV4_SRC:
178 ip = (IPCriterion) c;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800179 ip4Prefix = ip.ip().getIp4Prefix();
180 if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
181 Ip4Address maskAddr =
182 Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700183 Masked<IPv4Address> maskedIp =
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800184 Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700185 IPv4Address.of(maskAddr.toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700186 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
187 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700188 mBuilder.setExact(MatchField.IPV4_SRC,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800189 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700190 }
191 break;
192 case IP_PROTO:
193 IPProtocolCriterion p = (IPProtocolCriterion) c;
194 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
195 break;
196 case VLAN_PCP:
197 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
198 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
199 break;
200 case VLAN_VID:
201 VlanIdCriterion vid = (VlanIdCriterion) c;
202 mBuilder.setExact(MatchField.VLAN_VID,
203 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
204 break;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700205 case TCP_DST:
206 tp = (TcpPortCriterion) c;
207 mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
208 break;
209 case TCP_SRC:
210 tp = (TcpPortCriterion) c;
211 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
212 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800213 case MPLS_LABEL:
214 Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c;
215 mBuilder.setExact(MatchField.MPLS_LABEL,
216 U32.of(mp.label().intValue()));
217 break;
Marc De Leenheer49087752014-10-23 13:54:09 -0700218 case OCH_SIGID:
219 LambdaCriterion lc = (LambdaCriterion) c;
220 mBuilder.setExact(MatchField.OCH_SIGID,
221 new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
222 break;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -0800223 case OCH_SIGTYPE:
224 Criteria.OpticalSignalTypeCriterion sc =
225 (Criteria.OpticalSignalTypeCriterion) c;
226 mBuilder.setExact(MatchField.OCH_SIGTYPE,
227 U8.of(sc.signalType()));
228 break;
Charles M.C. Chan52fae7d2015-01-17 00:35:53 +0800229 case IPV6_DST:
230 ip = (IPCriterion) c;
231 ip6Prefix = ip.ip().getIp6Prefix();
232 if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
233 Ip6Address maskAddr =
234 Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
235 Masked<IPv6Address> maskedIp =
236 Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
237 IPv6Address.of(maskAddr.toString()));
238 mBuilder.setMasked(MatchField.IPV6_DST, maskedIp);
239 } else {
240 mBuilder.setExact(MatchField.IPV6_DST,
241 IPv6Address.of(ip6Prefix.address().toString()));
242 }
243 break;
244 case IPV6_SRC:
245 ip = (IPCriterion) c;
246 ip6Prefix = ip.ip().getIp6Prefix();
247 if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
248 Ip6Address maskAddr =
249 Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
250 Masked<IPv6Address> maskedIp =
251 Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
252 IPv6Address.of(maskAddr.toString()));
253 mBuilder.setMasked(MatchField.IPV6_SRC, maskedIp);
254 } else {
255 mBuilder.setExact(MatchField.IPV6_SRC,
256 IPv6Address.of(ip6Prefix.address().toString()));
257 }
258 break;
Kunihiro Ishiguro0f9aba82015-01-15 17:14:17 -0800259 case ICMPV6_TYPE:
260 Icmpv6TypeCriterion icmpv6type = (Icmpv6TypeCriterion) c;
261 mBuilder.setExact(MatchField.ICMPV6_TYPE,
262 U8.of(icmpv6type.icmpv6Type().byteValue()));
263 break;
264 case ICMPV6_CODE:
265 Icmpv6CodeCriterion icmpv6code = (Icmpv6CodeCriterion) c;
266 mBuilder.setExact(MatchField.ICMPV6_CODE,
267 U8.of(icmpv6code.icmpv6Code().byteValue()));
268 break;
alshabibeec3a062014-09-17 18:01:26 -0700269 case ARP_OP:
270 case ARP_SHA:
271 case ARP_SPA:
272 case ARP_THA:
273 case ARP_TPA:
274 case ICMPV4_CODE:
275 case ICMPV4_TYPE:
alshabibeec3a062014-09-17 18:01:26 -0700276 case IN_PHY_PORT:
alshabibeec3a062014-09-17 18:01:26 -0700277 case IPV6_EXTHDR:
278 case IPV6_FLABEL:
279 case IPV6_ND_SLL:
280 case IPV6_ND_TARGET:
281 case IPV6_ND_TLL:
alshabibeec3a062014-09-17 18:01:26 -0700282 case IP_DSCP:
283 case IP_ECN:
284 case METADATA:
285 case MPLS_BOS:
alshabibeec3a062014-09-17 18:01:26 -0700286 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
Jonathan Hart86e59352014-10-22 10:42:16 -0700300 /**
301 * Returns the flow rule for this builder.
302 *
303 * @return the flow rule
304 */
305 protected FlowRule flowRule() {
306 return flowRule;
307 }
alshabib219ebaa2014-09-22 15:41:24 -0700308
Jonathan Hart86e59352014-10-22 10:42:16 -0700309 /**
310 * Returns the factory used for building OpenFlow constructs.
311 *
312 * @return the factory
313 */
314 protected OFFactory factory() {
315 return factory;
316 }
alshabib219ebaa2014-09-22 15:41:24 -0700317
alshabibeec3a062014-09-17 18:01:26 -0700318}