blob: 58a57208053cc7dc4f235c415bf520aab35ba975 [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;
34import org.onosproject.net.flow.criteria.Criterion;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -080035import org.onlab.packet.Ip4Address;
36import org.onlab.packet.Ip4Prefix;
alshabibeec3a062014-09-17 18:01:26 -070037import org.projectfloodlight.openflow.protocol.OFFactory;
alshabib193525b2014-10-08 18:58:03 -070038import org.projectfloodlight.openflow.protocol.OFFlowAdd;
39import org.projectfloodlight.openflow.protocol.OFFlowDelete;
alshabibeec3a062014-09-17 18:01:26 -070040import org.projectfloodlight.openflow.protocol.OFFlowMod;
alshabibeec3a062014-09-17 18:01:26 -070041import org.projectfloodlight.openflow.protocol.match.Match;
42import org.projectfloodlight.openflow.protocol.match.MatchField;
Marc De Leenheer49087752014-10-23 13:54:09 -070043import org.projectfloodlight.openflow.types.CircuitSignalID;
alshabibeec3a062014-09-17 18:01:26 -070044import org.projectfloodlight.openflow.types.EthType;
45import org.projectfloodlight.openflow.types.IPv4Address;
Charles M.C. Chan52fae7d2015-01-17 00:35:53 +080046import org.projectfloodlight.openflow.types.IPv6Address;
alshabibeec3a062014-09-17 18:01:26 -070047import org.projectfloodlight.openflow.types.IpProtocol;
48import org.projectfloodlight.openflow.types.MacAddress;
49import org.projectfloodlight.openflow.types.Masked;
alshabibeec3a062014-09-17 18:01:26 -070050import org.projectfloodlight.openflow.types.OFPort;
51import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Jonathan Hart34bc6142014-10-17 11:00:43 -070052import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080053import org.projectfloodlight.openflow.types.U32;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -080054import org.projectfloodlight.openflow.types.U8;
alshabibeec3a062014-09-17 18:01:26 -070055import org.projectfloodlight.openflow.types.VlanPcp;
56import org.projectfloodlight.openflow.types.VlanVid;
57import org.slf4j.Logger;
58
Brian O'Connor427a1762014-11-19 18:40:32 -080059import java.util.Optional;
60
Jonathan Hart86e59352014-10-22 10:42:16 -070061/**
62 * Builder for OpenFlow flow mods based on FlowRules.
63 */
64public abstract class FlowModBuilder {
alshabibeec3a062014-09-17 18:01:26 -070065
66 private final Logger log = getLogger(getClass());
67
68 private final OFFactory factory;
Jonathan Hart86e59352014-10-22 10:42:16 -070069 private final FlowRule flowRule;
alshabibeec3a062014-09-17 18:01:26 -070070 private final TrafficSelector selector;
Brian O'Connor427a1762014-11-19 18:40:32 -080071 protected final Long xid;
alshabibeec3a062014-09-17 18:01:26 -070072
Jonathan Hart86e59352014-10-22 10:42:16 -070073 /**
74 * Creates a new flow mod builder.
75 *
76 * @param flowRule the flow rule to transform into a flow mod
77 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080078 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070079 * @return the new flow mod builder
80 */
Brian O'Connor427a1762014-11-19 18:40:32 -080081 public static FlowModBuilder builder(FlowRule flowRule,
82 OFFactory factory, Optional<Long> xid) {
Jonathan Hart86e59352014-10-22 10:42:16 -070083 switch (factory.getVersion()) {
84 case OF_10:
Brian O'Connor427a1762014-11-19 18:40:32 -080085 return new FlowModBuilderVer10(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070086 case OF_13:
Brian O'Connor427a1762014-11-19 18:40:32 -080087 return new FlowModBuilderVer13(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070088 default:
89 throw new UnsupportedOperationException(
90 "No flow mod builder for protocol version " + factory.getVersion());
91 }
92 }
alshabibeec3a062014-09-17 18:01:26 -070093
Jonathan Hart86e59352014-10-22 10:42:16 -070094 /**
95 * Constructs a flow mod builder.
96 *
97 * @param flowRule the flow rule to transform into a flow mod
98 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080099 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -0700100 */
Brian O'Connor427a1762014-11-19 18:40:32 -0800101 protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
alshabibeec3a062014-09-17 18:01:26 -0700102 this.factory = factory;
Jonathan Hart86e59352014-10-22 10:42:16 -0700103 this.flowRule = flowRule;
alshabibeec3a062014-09-17 18:01:26 -0700104 this.selector = flowRule.selector();
Brian O'Connor427a1762014-11-19 18:40:32 -0800105 this.xid = xid.orElse((long) 0);
106
alshabibeec3a062014-09-17 18:01:26 -0700107 }
108
Jonathan Hart86e59352014-10-22 10:42:16 -0700109 /**
110 * Builds an ADD flow mod.
111 *
112 * @return the flow mod
113 */
114 public abstract OFFlowAdd buildFlowAdd();
alshabibeec3a062014-09-17 18:01:26 -0700115
Jonathan Hart86e59352014-10-22 10:42:16 -0700116 /**
117 * Builds a MODIFY flow mod.
118 *
119 * @return the flow mod
120 */
121 public abstract OFFlowMod buildFlowMod();
alshabibeec3a062014-09-17 18:01:26 -0700122
Jonathan Hart86e59352014-10-22 10:42:16 -0700123 /**
124 * Builds a DELETE flow mod.
125 *
126 * @return the flow mod
127 */
128 public abstract OFFlowDelete buildFlowDel();
alshabibeec3a062014-09-17 18:01:26 -0700129
Jonathan Hart86e59352014-10-22 10:42:16 -0700130 /**
131 * Builds the match for the flow mod.
132 *
133 * @return the match
134 */
135 protected Match buildMatch() {
alshabibeec3a062014-09-17 18:01:26 -0700136 Match.Builder mBuilder = factory.buildMatch();
137 EthCriterion eth;
138 IPCriterion ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800139 Ip4Prefix ip4Prefix;
Charles M.C. Chan52fae7d2015-01-17 00:35:53 +0800140 Ip6Prefix ip6Prefix;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700141 TcpPortCriterion tp;
alshabibeec3a062014-09-17 18:01:26 -0700142 for (Criterion c : selector.criteria()) {
143 switch (c.type()) {
144 case IN_PORT:
145 PortCriterion inport = (PortCriterion) c;
146 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
147 break;
148 case ETH_SRC:
149 eth = (EthCriterion) c;
150 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
151 break;
152 case ETH_DST:
153 eth = (EthCriterion) c;
154 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
155 break;
156 case ETH_TYPE:
157 EthTypeCriterion ethType = (EthTypeCriterion) c;
158 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
159 break;
160 case IPV4_DST:
161 ip = (IPCriterion) c;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800162 ip4Prefix = ip.ip().getIp4Prefix();
163 if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
164 Ip4Address maskAddr =
165 Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700166 Masked<IPv4Address> maskedIp =
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800167 Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700168 IPv4Address.of(maskAddr.toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700169 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
170 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700171 mBuilder.setExact(MatchField.IPV4_DST,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800172 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700173 }
174 break;
175 case IPV4_SRC:
176 ip = (IPCriterion) c;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800177 ip4Prefix = ip.ip().getIp4Prefix();
178 if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
179 Ip4Address maskAddr =
180 Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700181 Masked<IPv4Address> maskedIp =
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800182 Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700183 IPv4Address.of(maskAddr.toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700184 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
185 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700186 mBuilder.setExact(MatchField.IPV4_SRC,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800187 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700188 }
189 break;
190 case IP_PROTO:
191 IPProtocolCriterion p = (IPProtocolCriterion) c;
192 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
193 break;
194 case VLAN_PCP:
195 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
196 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
197 break;
198 case VLAN_VID:
199 VlanIdCriterion vid = (VlanIdCriterion) c;
200 mBuilder.setExact(MatchField.VLAN_VID,
201 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
202 break;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700203 case TCP_DST:
204 tp = (TcpPortCriterion) c;
205 mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
206 break;
207 case TCP_SRC:
208 tp = (TcpPortCriterion) c;
209 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
210 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800211 case MPLS_LABEL:
212 Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c;
213 mBuilder.setExact(MatchField.MPLS_LABEL,
214 U32.of(mp.label().intValue()));
215 break;
Marc De Leenheer49087752014-10-23 13:54:09 -0700216 case OCH_SIGID:
217 LambdaCriterion lc = (LambdaCriterion) c;
218 mBuilder.setExact(MatchField.OCH_SIGID,
219 new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
220 break;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -0800221 case OCH_SIGTYPE:
222 Criteria.OpticalSignalTypeCriterion sc =
223 (Criteria.OpticalSignalTypeCriterion) c;
224 mBuilder.setExact(MatchField.OCH_SIGTYPE,
225 U8.of(sc.signalType()));
226 break;
Charles M.C. Chan52fae7d2015-01-17 00:35:53 +0800227 case IPV6_DST:
228 ip = (IPCriterion) c;
229 ip6Prefix = ip.ip().getIp6Prefix();
230 if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
231 Ip6Address maskAddr =
232 Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
233 Masked<IPv6Address> maskedIp =
234 Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
235 IPv6Address.of(maskAddr.toString()));
236 mBuilder.setMasked(MatchField.IPV6_DST, maskedIp);
237 } else {
238 mBuilder.setExact(MatchField.IPV6_DST,
239 IPv6Address.of(ip6Prefix.address().toString()));
240 }
241 break;
242 case IPV6_SRC:
243 ip = (IPCriterion) c;
244 ip6Prefix = ip.ip().getIp6Prefix();
245 if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
246 Ip6Address maskAddr =
247 Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
248 Masked<IPv6Address> maskedIp =
249 Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
250 IPv6Address.of(maskAddr.toString()));
251 mBuilder.setMasked(MatchField.IPV6_SRC, maskedIp);
252 } else {
253 mBuilder.setExact(MatchField.IPV6_SRC,
254 IPv6Address.of(ip6Prefix.address().toString()));
255 }
256 break;
alshabibeec3a062014-09-17 18:01:26 -0700257 case ARP_OP:
258 case ARP_SHA:
259 case ARP_SPA:
260 case ARP_THA:
261 case ARP_TPA:
262 case ICMPV4_CODE:
263 case ICMPV4_TYPE:
264 case ICMPV6_CODE:
265 case ICMPV6_TYPE:
266 case IN_PHY_PORT:
alshabibeec3a062014-09-17 18:01:26 -0700267 case IPV6_EXTHDR:
268 case IPV6_FLABEL:
269 case IPV6_ND_SLL:
270 case IPV6_ND_TARGET:
271 case IPV6_ND_TLL:
alshabibeec3a062014-09-17 18:01:26 -0700272 case IP_DSCP:
273 case IP_ECN:
274 case METADATA:
275 case MPLS_BOS:
alshabibeec3a062014-09-17 18:01:26 -0700276 case MPLS_TC:
277 case PBB_ISID:
278 case SCTP_DST:
279 case SCTP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700280 case TUNNEL_ID:
281 case UDP_DST:
282 case UDP_SRC:
283 default:
284 log.warn("Match type {} not yet implemented.", c.type());
285 }
286 }
287 return mBuilder.build();
288 }
289
Jonathan Hart86e59352014-10-22 10:42:16 -0700290 /**
291 * Returns the flow rule for this builder.
292 *
293 * @return the flow rule
294 */
295 protected FlowRule flowRule() {
296 return flowRule;
297 }
alshabib219ebaa2014-09-22 15:41:24 -0700298
Jonathan Hart86e59352014-10-22 10:42:16 -0700299 /**
300 * Returns the factory used for building OpenFlow constructs.
301 *
302 * @return the factory
303 */
304 protected OFFactory factory() {
305 return factory;
306 }
alshabib219ebaa2014-09-22 15:41:24 -0700307
alshabibeec3a062014-09-17 18:01:26 -0700308}