blob: 1e9256f8fd9f4c64d73a3d5b12542599dc9fbf70 [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 */
alshabibeec3a062014-09-17 18:01:26 -070016package org.onlab.onos.provider.of.flow.impl;
17
18import static org.slf4j.LoggerFactory.getLogger;
19
alshabibeec3a062014-09-17 18:01:26 -070020import org.onlab.onos.net.flow.FlowRule;
21import org.onlab.onos.net.flow.TrafficSelector;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -080022import org.onlab.onos.net.flow.criteria.Criteria;
alshabibeec3a062014-09-17 18:01:26 -070023import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
24import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
25import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
26import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
Marc De Leenheer49087752014-10-23 13:54:09 -070027import org.onlab.onos.net.flow.criteria.Criteria.LambdaCriterion;
alshabibeec3a062014-09-17 18:01:26 -070028import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
Jonathan Hart34bc6142014-10-17 11:00:43 -070029import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
alshabibeec3a062014-09-17 18:01:26 -070030import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
31import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
32import org.onlab.onos.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 Balakrishnan2dd5abd2014-11-03 14:56:28 -080050import org.projectfloodlight.openflow.types.U8;
alshabibeec3a062014-09-17 18:01:26 -070051import org.projectfloodlight.openflow.types.VlanPcp;
52import org.projectfloodlight.openflow.types.VlanVid;
53import org.slf4j.Logger;
54
Jonathan Hart86e59352014-10-22 10:42:16 -070055/**
56 * Builder for OpenFlow flow mods based on FlowRules.
57 */
58public abstract class FlowModBuilder {
alshabibeec3a062014-09-17 18:01:26 -070059
60 private final Logger log = getLogger(getClass());
61
62 private final OFFactory factory;
Jonathan Hart86e59352014-10-22 10:42:16 -070063 private final FlowRule flowRule;
alshabibeec3a062014-09-17 18:01:26 -070064 private final TrafficSelector selector;
65
Jonathan Hart86e59352014-10-22 10:42:16 -070066 /**
67 * Creates a new flow mod builder.
68 *
69 * @param flowRule the flow rule to transform into a flow mod
70 * @param factory the OpenFlow factory to use to build the flow mod
71 * @return the new flow mod builder
72 */
73 public static FlowModBuilder builder(FlowRule flowRule, OFFactory factory) {
74 switch (factory.getVersion()) {
75 case OF_10:
76 return new FlowModBuilderVer10(flowRule, factory);
77 case OF_13:
78 return new FlowModBuilderVer13(flowRule, factory);
79 default:
80 throw new UnsupportedOperationException(
81 "No flow mod builder for protocol version " + factory.getVersion());
82 }
83 }
alshabibeec3a062014-09-17 18:01:26 -070084
Jonathan Hart86e59352014-10-22 10:42:16 -070085 /**
86 * Constructs a flow mod builder.
87 *
88 * @param flowRule the flow rule to transform into a flow mod
89 * @param factory the OpenFlow factory to use to build the flow mod
90 */
91 protected FlowModBuilder(FlowRule flowRule, OFFactory factory) {
alshabibeec3a062014-09-17 18:01:26 -070092 this.factory = factory;
Jonathan Hart86e59352014-10-22 10:42:16 -070093 this.flowRule = flowRule;
alshabibeec3a062014-09-17 18:01:26 -070094 this.selector = flowRule.selector();
alshabibeec3a062014-09-17 18:01:26 -070095 }
96
Jonathan Hart86e59352014-10-22 10:42:16 -070097 /**
98 * Builds an ADD flow mod.
99 *
100 * @return the flow mod
101 */
102 public abstract OFFlowAdd buildFlowAdd();
alshabibeec3a062014-09-17 18:01:26 -0700103
Jonathan Hart86e59352014-10-22 10:42:16 -0700104 /**
105 * Builds a MODIFY flow mod.
106 *
107 * @return the flow mod
108 */
109 public abstract OFFlowMod buildFlowMod();
alshabibeec3a062014-09-17 18:01:26 -0700110
Jonathan Hart86e59352014-10-22 10:42:16 -0700111 /**
112 * Builds a DELETE flow mod.
113 *
114 * @return the flow mod
115 */
116 public abstract OFFlowDelete buildFlowDel();
alshabibeec3a062014-09-17 18:01:26 -0700117
Jonathan Hart86e59352014-10-22 10:42:16 -0700118 /**
119 * Builds the match for the flow mod.
120 *
121 * @return the match
122 */
123 protected Match buildMatch() {
alshabibeec3a062014-09-17 18:01:26 -0700124 Match.Builder mBuilder = factory.buildMatch();
125 EthCriterion eth;
126 IPCriterion ip;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800127 Ip4Prefix ip4Prefix;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700128 TcpPortCriterion tp;
alshabibeec3a062014-09-17 18:01:26 -0700129 for (Criterion c : selector.criteria()) {
130 switch (c.type()) {
131 case IN_PORT:
132 PortCriterion inport = (PortCriterion) c;
133 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
134 break;
135 case ETH_SRC:
136 eth = (EthCriterion) c;
137 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
138 break;
139 case ETH_DST:
140 eth = (EthCriterion) c;
141 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
142 break;
143 case ETH_TYPE:
144 EthTypeCriterion ethType = (EthTypeCriterion) c;
145 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
146 break;
147 case IPV4_DST:
148 ip = (IPCriterion) c;
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800149 ip4Prefix = ip.ip().getIp4Prefix();
150 if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
151 Ip4Address maskAddr =
152 Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700153 Masked<IPv4Address> maskedIp =
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800154 Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700155 IPv4Address.of(maskAddr.toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700156 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
157 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700158 mBuilder.setExact(MatchField.IPV4_DST,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800159 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700160 }
161 break;
162 case IPV4_SRC:
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_SRC, maskedIp);
172 } else {
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700173 mBuilder.setExact(MatchField.IPV4_SRC,
Pavlin Radoslavov23e398d2014-11-05 15:17:57 -0800174 IPv4Address.of(ip4Prefix.address().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700175 }
176 break;
177 case IP_PROTO:
178 IPProtocolCriterion p = (IPProtocolCriterion) c;
179 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
180 break;
181 case VLAN_PCP:
182 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
183 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
184 break;
185 case VLAN_VID:
186 VlanIdCriterion vid = (VlanIdCriterion) c;
187 mBuilder.setExact(MatchField.VLAN_VID,
188 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
189 break;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700190 case TCP_DST:
191 tp = (TcpPortCriterion) c;
192 mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
193 break;
194 case TCP_SRC:
195 tp = (TcpPortCriterion) c;
196 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
197 break;
Marc De Leenheer49087752014-10-23 13:54:09 -0700198 case OCH_SIGID:
199 LambdaCriterion lc = (LambdaCriterion) c;
200 mBuilder.setExact(MatchField.OCH_SIGID,
201 new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
202 break;
Praseed Balakrishnan2dd5abd2014-11-03 14:56:28 -0800203 case OCH_SIGTYPE:
204 Criteria.OpticalSignalTypeCriterion sc =
205 (Criteria.OpticalSignalTypeCriterion) c;
206 mBuilder.setExact(MatchField.OCH_SIGTYPE,
207 U8.of(sc.signalType()));
208 break;
alshabibeec3a062014-09-17 18:01:26 -0700209 case ARP_OP:
210 case ARP_SHA:
211 case ARP_SPA:
212 case ARP_THA:
213 case ARP_TPA:
214 case ICMPV4_CODE:
215 case ICMPV4_TYPE:
216 case ICMPV6_CODE:
217 case ICMPV6_TYPE:
218 case IN_PHY_PORT:
219 case IPV6_DST:
220 case IPV6_EXTHDR:
221 case IPV6_FLABEL:
222 case IPV6_ND_SLL:
223 case IPV6_ND_TARGET:
224 case IPV6_ND_TLL:
225 case IPV6_SRC:
226 case IP_DSCP:
227 case IP_ECN:
228 case METADATA:
229 case MPLS_BOS:
230 case MPLS_LABEL:
231 case MPLS_TC:
232 case PBB_ISID:
233 case SCTP_DST:
234 case SCTP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700235 case TUNNEL_ID:
236 case UDP_DST:
237 case UDP_SRC:
238 default:
239 log.warn("Match type {} not yet implemented.", c.type());
240 }
241 }
242 return mBuilder.build();
243 }
244
Jonathan Hart86e59352014-10-22 10:42:16 -0700245 /**
246 * Returns the flow rule for this builder.
247 *
248 * @return the flow rule
249 */
250 protected FlowRule flowRule() {
251 return flowRule;
252 }
alshabib219ebaa2014-09-22 15:41:24 -0700253
Jonathan Hart86e59352014-10-22 10:42:16 -0700254 /**
255 * Returns the factory used for building OpenFlow constructs.
256 *
257 * @return the factory
258 */
259 protected OFFactory factory() {
260 return factory;
261 }
alshabib219ebaa2014-09-22 15:41:24 -0700262
alshabibeec3a062014-09-17 18:01:26 -0700263}