blob: 9f483c3eb24d824ed12f24f12d0711e1da37cd9a [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
Brian O'Connorabafb502014-12-02 22:26:20 -080020import org.onosproject.net.flow.FlowRule;
21import org.onosproject.net.flow.TrafficSelector;
22import org.onosproject.net.flow.criteria.Criteria;
23import org.onosproject.net.flow.criteria.Criteria.EthCriterion;
24import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion;
25import org.onosproject.net.flow.criteria.Criteria.IPCriterion;
26import org.onosproject.net.flow.criteria.Criteria.IPProtocolCriterion;
27import org.onosproject.net.flow.criteria.Criteria.LambdaCriterion;
28import org.onosproject.net.flow.criteria.Criteria.PortCriterion;
29import org.onosproject.net.flow.criteria.Criteria.TcpPortCriterion;
30import org.onosproject.net.flow.criteria.Criteria.VlanIdCriterion;
31import org.onosproject.net.flow.criteria.Criteria.VlanPcpCriterion;
32import org.onosproject.net.flow.criteria.Criterion;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -080033import org.onlab.packet.Ip4Address;
34import org.onlab.packet.Ip4Prefix;
alshabibeec3a062014-09-17 18:01:26 -070035import org.projectfloodlight.openflow.protocol.OFFactory;
alshabib193525b2014-10-08 18:58:03 -070036import org.projectfloodlight.openflow.protocol.OFFlowAdd;
37import org.projectfloodlight.openflow.protocol.OFFlowDelete;
alshabibeec3a062014-09-17 18:01:26 -070038import org.projectfloodlight.openflow.protocol.OFFlowMod;
alshabibeec3a062014-09-17 18:01:26 -070039import 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;
alshabibeec3a062014-09-17 18:01:26 -070047import org.projectfloodlight.openflow.types.OFPort;
48import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Jonathan Hart34bc6142014-10-17 11:00:43 -070049import org.projectfloodlight.openflow.types.TransportPort;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080050import org.projectfloodlight.openflow.types.U32;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -080051import org.projectfloodlight.openflow.types.U8;
alshabibeec3a062014-09-17 18:01:26 -070052import org.projectfloodlight.openflow.types.VlanPcp;
53import org.projectfloodlight.openflow.types.VlanVid;
54import org.slf4j.Logger;
55
Brian O'Connor427a1762014-11-19 18:40:32 -080056import java.util.Optional;
57
Jonathan Hart86e59352014-10-22 10:42:16 -070058/**
59 * Builder for OpenFlow flow mods based on FlowRules.
60 */
61public abstract class FlowModBuilder {
alshabibeec3a062014-09-17 18:01:26 -070062
63 private final Logger log = getLogger(getClass());
64
65 private final OFFactory factory;
Jonathan Hart86e59352014-10-22 10:42:16 -070066 private final FlowRule flowRule;
alshabibeec3a062014-09-17 18:01:26 -070067 private final TrafficSelector selector;
Brian O'Connor427a1762014-11-19 18:40:32 -080068 protected final Long xid;
alshabibeec3a062014-09-17 18:01:26 -070069
Jonathan Hart86e59352014-10-22 10:42:16 -070070 /**
71 * Creates a new flow mod builder.
72 *
73 * @param flowRule the flow rule to transform into a flow mod
74 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080075 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070076 * @return the new flow mod builder
77 */
Brian O'Connor427a1762014-11-19 18:40:32 -080078 public static FlowModBuilder builder(FlowRule flowRule,
79 OFFactory factory, Optional<Long> xid) {
Jonathan Hart86e59352014-10-22 10:42:16 -070080 switch (factory.getVersion()) {
81 case OF_10:
Brian O'Connor427a1762014-11-19 18:40:32 -080082 return new FlowModBuilderVer10(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070083 case OF_13:
Brian O'Connor427a1762014-11-19 18:40:32 -080084 return new FlowModBuilderVer13(flowRule, factory, xid);
Jonathan Hart86e59352014-10-22 10:42:16 -070085 default:
86 throw new UnsupportedOperationException(
87 "No flow mod builder for protocol version " + factory.getVersion());
88 }
89 }
alshabibeec3a062014-09-17 18:01:26 -070090
Jonathan Hart86e59352014-10-22 10:42:16 -070091 /**
92 * Constructs a flow mod builder.
93 *
94 * @param flowRule the flow rule to transform into a flow mod
95 * @param factory the OpenFlow factory to use to build the flow mod
Pavlin Radoslavov119fd5c2014-11-25 19:08:19 -080096 * @param xid the transaction ID
Jonathan Hart86e59352014-10-22 10:42:16 -070097 */
Brian O'Connor427a1762014-11-19 18:40:32 -080098 protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
alshabibeec3a062014-09-17 18:01:26 -070099 this.factory = factory;
Jonathan Hart86e59352014-10-22 10:42:16 -0700100 this.flowRule = flowRule;
alshabibeec3a062014-09-17 18:01:26 -0700101 this.selector = flowRule.selector();
Brian O'Connor427a1762014-11-19 18:40:32 -0800102 this.xid = xid.orElse((long) 0);
103
alshabibeec3a062014-09-17 18:01:26 -0700104 }
105
Jonathan Hart86e59352014-10-22 10:42:16 -0700106 /**
107 * Builds an ADD flow mod.
108 *
109 * @return the flow mod
110 */
111 public abstract OFFlowAdd buildFlowAdd();
alshabibeec3a062014-09-17 18:01:26 -0700112
Jonathan Hart86e59352014-10-22 10:42:16 -0700113 /**
114 * Builds a MODIFY flow mod.
115 *
116 * @return the flow mod
117 */
118 public abstract OFFlowMod buildFlowMod();
alshabibeec3a062014-09-17 18:01:26 -0700119
Jonathan Hart86e59352014-10-22 10:42:16 -0700120 /**
121 * Builds a DELETE flow mod.
122 *
123 * @return the flow mod
124 */
125 public abstract OFFlowDelete buildFlowDel();
alshabibeec3a062014-09-17 18:01:26 -0700126
Jonathan Hart86e59352014-10-22 10:42:16 -0700127 /**
128 * Builds the match for the flow mod.
129 *
130 * @return the match
131 */
132 protected Match buildMatch() {
alshabibeec3a062014-09-17 18:01:26 -0700133 Match.Builder mBuilder = factory.buildMatch();
134 EthCriterion eth;
135 IPCriterion ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800136 Ip4Prefix ip4Prefix;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700137 TcpPortCriterion tp;
alshabibeec3a062014-09-17 18:01:26 -0700138 for (Criterion c : selector.criteria()) {
139 switch (c.type()) {
140 case IN_PORT:
141 PortCriterion inport = (PortCriterion) c;
142 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
143 break;
144 case ETH_SRC:
145 eth = (EthCriterion) c;
146 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
147 break;
148 case ETH_DST:
149 eth = (EthCriterion) c;
150 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
151 break;
152 case ETH_TYPE:
153 EthTypeCriterion ethType = (EthTypeCriterion) c;
154 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
155 break;
156 case IPV4_DST:
157 ip = (IPCriterion) c;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800158 ip4Prefix = ip.ip().getIp4Prefix();
159 if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
160 Ip4Address maskAddr =
161 Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700162 Masked<IPv4Address> maskedIp =
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800163 Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700164 IPv4Address.of(maskAddr.toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700165 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
166 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700167 mBuilder.setExact(MatchField.IPV4_DST,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800168 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700169 }
170 break;
171 case IPV4_SRC:
172 ip = (IPCriterion) c;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800173 ip4Prefix = ip.ip().getIp4Prefix();
174 if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
175 Ip4Address maskAddr =
176 Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700177 Masked<IPv4Address> maskedIp =
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800178 Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700179 IPv4Address.of(maskAddr.toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700180 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
181 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700182 mBuilder.setExact(MatchField.IPV4_SRC,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800183 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700184 }
185 break;
186 case IP_PROTO:
187 IPProtocolCriterion p = (IPProtocolCriterion) c;
188 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
189 break;
190 case VLAN_PCP:
191 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
192 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
193 break;
194 case VLAN_VID:
195 VlanIdCriterion vid = (VlanIdCriterion) c;
196 mBuilder.setExact(MatchField.VLAN_VID,
197 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
198 break;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700199 case TCP_DST:
200 tp = (TcpPortCriterion) c;
201 mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
202 break;
203 case TCP_SRC:
204 tp = (TcpPortCriterion) c;
205 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
206 break;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800207 case MPLS_LABEL:
208 Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c;
209 mBuilder.setExact(MatchField.MPLS_LABEL,
210 U32.of(mp.label().intValue()));
211 break;
Marc De Leenheer49087752014-10-23 13:54:09 -0700212 case OCH_SIGID:
213 LambdaCriterion lc = (LambdaCriterion) c;
214 mBuilder.setExact(MatchField.OCH_SIGID,
215 new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
216 break;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -0800217 case OCH_SIGTYPE:
218 Criteria.OpticalSignalTypeCriterion sc =
219 (Criteria.OpticalSignalTypeCriterion) c;
220 mBuilder.setExact(MatchField.OCH_SIGTYPE,
221 U8.of(sc.signalType()));
222 break;
alshabibeec3a062014-09-17 18:01:26 -0700223 case ARP_OP:
224 case ARP_SHA:
225 case ARP_SPA:
226 case ARP_THA:
227 case ARP_TPA:
228 case ICMPV4_CODE:
229 case ICMPV4_TYPE:
230 case ICMPV6_CODE:
231 case ICMPV6_TYPE:
232 case IN_PHY_PORT:
233 case IPV6_DST:
234 case IPV6_EXTHDR:
235 case IPV6_FLABEL:
236 case IPV6_ND_SLL:
237 case IPV6_ND_TARGET:
238 case IPV6_ND_TLL:
239 case IPV6_SRC:
240 case IP_DSCP:
241 case IP_ECN:
242 case METADATA:
243 case MPLS_BOS:
alshabibeec3a062014-09-17 18:01:26 -0700244 case MPLS_TC:
245 case PBB_ISID:
246 case SCTP_DST:
247 case SCTP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700248 case TUNNEL_ID:
249 case UDP_DST:
250 case UDP_SRC:
251 default:
252 log.warn("Match type {} not yet implemented.", c.type());
253 }
254 }
255 return mBuilder.build();
256 }
257
Jonathan Hart86e59352014-10-22 10:42:16 -0700258 /**
259 * Returns the flow rule for this builder.
260 *
261 * @return the flow rule
262 */
263 protected FlowRule flowRule() {
264 return flowRule;
265 }
alshabib219ebaa2014-09-22 15:41:24 -0700266
Jonathan Hart86e59352014-10-22 10:42:16 -0700267 /**
268 * Returns the factory used for building OpenFlow constructs.
269 *
270 * @return the factory
271 */
272 protected OFFactory factory() {
273 return factory;
274 }
alshabib219ebaa2014-09-22 15:41:24 -0700275
alshabibeec3a062014-09-17 18:01:26 -0700276}