blob: e0fb7d9a5d28c9feb3df2bdf81df3a0e7354083e [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
alshabibeec3a062014-09-17 18:01:26 -07005import org.onlab.onos.net.flow.FlowRule;
6import org.onlab.onos.net.flow.TrafficSelector;
alshabibeec3a062014-09-17 18:01:26 -07007import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
8import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
9import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
10import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
Marc De Leenheer49087752014-10-23 13:54:09 -070011import org.onlab.onos.net.flow.criteria.Criteria.LambdaCriterion;
alshabibeec3a062014-09-17 18:01:26 -070012import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
Jonathan Hart34bc6142014-10-17 11:00:43 -070013import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
alshabibeec3a062014-09-17 18:01:26 -070014import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
15import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
16import org.onlab.onos.net.flow.criteria.Criterion;
alshabibeec3a062014-09-17 18:01:26 -070017import org.projectfloodlight.openflow.protocol.OFFactory;
alshabib193525b2014-10-08 18:58:03 -070018import org.projectfloodlight.openflow.protocol.OFFlowAdd;
19import org.projectfloodlight.openflow.protocol.OFFlowDelete;
alshabibeec3a062014-09-17 18:01:26 -070020import org.projectfloodlight.openflow.protocol.OFFlowMod;
alshabibeec3a062014-09-17 18:01:26 -070021import org.projectfloodlight.openflow.protocol.match.Match;
22import org.projectfloodlight.openflow.protocol.match.MatchField;
Marc De Leenheer49087752014-10-23 13:54:09 -070023import org.projectfloodlight.openflow.types.CircuitSignalID;
alshabibeec3a062014-09-17 18:01:26 -070024import org.projectfloodlight.openflow.types.EthType;
25import org.projectfloodlight.openflow.types.IPv4Address;
26import org.projectfloodlight.openflow.types.IpProtocol;
27import org.projectfloodlight.openflow.types.MacAddress;
28import org.projectfloodlight.openflow.types.Masked;
alshabibeec3a062014-09-17 18:01:26 -070029import org.projectfloodlight.openflow.types.OFPort;
30import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Jonathan Hart34bc6142014-10-17 11:00:43 -070031import org.projectfloodlight.openflow.types.TransportPort;
alshabibeec3a062014-09-17 18:01:26 -070032import org.projectfloodlight.openflow.types.VlanPcp;
33import org.projectfloodlight.openflow.types.VlanVid;
34import org.slf4j.Logger;
35
Jonathan Hart86e59352014-10-22 10:42:16 -070036/**
37 * Builder for OpenFlow flow mods based on FlowRules.
38 */
39public abstract class FlowModBuilder {
alshabibeec3a062014-09-17 18:01:26 -070040
41 private final Logger log = getLogger(getClass());
42
43 private final OFFactory factory;
Jonathan Hart86e59352014-10-22 10:42:16 -070044 private final FlowRule flowRule;
alshabibeec3a062014-09-17 18:01:26 -070045 private final TrafficSelector selector;
46
Jonathan Hart86e59352014-10-22 10:42:16 -070047 /**
48 * Creates a new flow mod builder.
49 *
50 * @param flowRule the flow rule to transform into a flow mod
51 * @param factory the OpenFlow factory to use to build the flow mod
52 * @return the new flow mod builder
53 */
54 public static FlowModBuilder builder(FlowRule flowRule, OFFactory factory) {
55 switch (factory.getVersion()) {
56 case OF_10:
57 return new FlowModBuilderVer10(flowRule, factory);
58 case OF_13:
59 return new FlowModBuilderVer13(flowRule, factory);
60 default:
61 throw new UnsupportedOperationException(
62 "No flow mod builder for protocol version " + factory.getVersion());
63 }
64 }
alshabibeec3a062014-09-17 18:01:26 -070065
Jonathan Hart86e59352014-10-22 10:42:16 -070066 /**
67 * Constructs a 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 */
72 protected FlowModBuilder(FlowRule flowRule, OFFactory factory) {
alshabibeec3a062014-09-17 18:01:26 -070073 this.factory = factory;
Jonathan Hart86e59352014-10-22 10:42:16 -070074 this.flowRule = flowRule;
alshabibeec3a062014-09-17 18:01:26 -070075 this.selector = flowRule.selector();
alshabibeec3a062014-09-17 18:01:26 -070076 }
77
Jonathan Hart86e59352014-10-22 10:42:16 -070078 /**
79 * Builds an ADD flow mod.
80 *
81 * @return the flow mod
82 */
83 public abstract OFFlowAdd buildFlowAdd();
alshabibeec3a062014-09-17 18:01:26 -070084
Jonathan Hart86e59352014-10-22 10:42:16 -070085 /**
86 * Builds a MODIFY flow mod.
87 *
88 * @return the flow mod
89 */
90 public abstract OFFlowMod buildFlowMod();
alshabibeec3a062014-09-17 18:01:26 -070091
Jonathan Hart86e59352014-10-22 10:42:16 -070092 /**
93 * Builds a DELETE flow mod.
94 *
95 * @return the flow mod
96 */
97 public abstract OFFlowDelete buildFlowDel();
alshabibeec3a062014-09-17 18:01:26 -070098
Jonathan Hart86e59352014-10-22 10:42:16 -070099 /**
100 * Builds the match for the flow mod.
101 *
102 * @return the match
103 */
104 protected Match buildMatch() {
alshabibeec3a062014-09-17 18:01:26 -0700105 Match.Builder mBuilder = factory.buildMatch();
106 EthCriterion eth;
107 IPCriterion ip;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700108 TcpPortCriterion tp;
alshabibeec3a062014-09-17 18:01:26 -0700109 for (Criterion c : selector.criteria()) {
110 switch (c.type()) {
111 case IN_PORT:
112 PortCriterion inport = (PortCriterion) c;
113 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
114 break;
115 case ETH_SRC:
116 eth = (EthCriterion) c;
117 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
118 break;
119 case ETH_DST:
120 eth = (EthCriterion) c;
121 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
122 break;
123 case ETH_TYPE:
124 EthTypeCriterion ethType = (EthTypeCriterion) c;
125 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
126 break;
127 case IPV4_DST:
128 ip = (IPCriterion) c;
129 if (ip.ip().isMasked()) {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700130 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
131 IPv4Address.of(ip.ip().netmask().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700132 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
133 } else {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700134 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700135 }
136 break;
137 case IPV4_SRC:
138 ip = (IPCriterion) c;
139 if (ip.ip().isMasked()) {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700140 Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()),
141 IPv4Address.of(ip.ip().netmask().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700142 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
143 } else {
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700144 mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
alshabibeec3a062014-09-17 18:01:26 -0700145 }
146 break;
147 case IP_PROTO:
148 IPProtocolCriterion p = (IPProtocolCriterion) c;
149 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
150 break;
151 case VLAN_PCP:
152 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
153 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
154 break;
155 case VLAN_VID:
156 VlanIdCriterion vid = (VlanIdCriterion) c;
157 mBuilder.setExact(MatchField.VLAN_VID,
158 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
159 break;
Jonathan Hart34bc6142014-10-17 11:00:43 -0700160 case TCP_DST:
161 tp = (TcpPortCriterion) c;
162 mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
163 break;
164 case TCP_SRC:
165 tp = (TcpPortCriterion) c;
166 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
167 break;
Marc De Leenheer49087752014-10-23 13:54:09 -0700168 case OCH_SIGID:
169 LambdaCriterion lc = (LambdaCriterion) c;
170 mBuilder.setExact(MatchField.OCH_SIGID,
171 new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
172 break;
alshabibeec3a062014-09-17 18:01:26 -0700173 case ARP_OP:
174 case ARP_SHA:
175 case ARP_SPA:
176 case ARP_THA:
177 case ARP_TPA:
178 case ICMPV4_CODE:
179 case ICMPV4_TYPE:
180 case ICMPV6_CODE:
181 case ICMPV6_TYPE:
182 case IN_PHY_PORT:
183 case IPV6_DST:
184 case IPV6_EXTHDR:
185 case IPV6_FLABEL:
186 case IPV6_ND_SLL:
187 case IPV6_ND_TARGET:
188 case IPV6_ND_TLL:
189 case IPV6_SRC:
190 case IP_DSCP:
191 case IP_ECN:
192 case METADATA:
193 case MPLS_BOS:
194 case MPLS_LABEL:
195 case MPLS_TC:
196 case PBB_ISID:
197 case SCTP_DST:
198 case SCTP_SRC:
alshabibeec3a062014-09-17 18:01:26 -0700199 case TUNNEL_ID:
200 case UDP_DST:
201 case UDP_SRC:
202 default:
203 log.warn("Match type {} not yet implemented.", c.type());
204 }
205 }
206 return mBuilder.build();
207 }
208
Jonathan Hart86e59352014-10-22 10:42:16 -0700209 /**
210 * Returns the flow rule for this builder.
211 *
212 * @return the flow rule
213 */
214 protected FlowRule flowRule() {
215 return flowRule;
216 }
alshabib219ebaa2014-09-22 15:41:24 -0700217
Jonathan Hart86e59352014-10-22 10:42:16 -0700218 /**
219 * Returns the factory used for building OpenFlow constructs.
220 *
221 * @return the factory
222 */
223 protected OFFactory factory() {
224 return factory;
225 }
alshabib219ebaa2014-09-22 15:41:24 -0700226
alshabibeec3a062014-09-17 18:01:26 -0700227}