blob: 82fcedeec2cc458ca602752bc426d2c9b507df76 [file] [log] [blame]
alshabib6b5cfec2014-09-18 17:42:18 -07001package org.onlab.onos.provider.of.flow.impl;
2
3import static org.slf4j.LoggerFactory.getLogger;
4
5import java.util.List;
6
7import org.onlab.onos.net.DeviceId;
8import org.onlab.onos.net.PortNumber;
9import org.onlab.onos.net.flow.DefaultFlowRule;
10import org.onlab.onos.net.flow.DefaultTrafficSelector;
11import org.onlab.onos.net.flow.DefaultTrafficTreatment;
12import org.onlab.onos.net.flow.FlowRule;
alshabiba7f7ca82014-09-22 11:41:23 -070013import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
alshabib6b5cfec2014-09-18 17:42:18 -070014import org.onlab.onos.net.flow.TrafficSelector;
15import org.onlab.onos.net.flow.TrafficTreatment;
alshabib6b5cfec2014-09-18 17:42:18 -070016import org.onlab.onos.openflow.controller.Dpid;
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070017import org.onlab.packet.IpPrefix;
alshabib6b5cfec2014-09-18 17:42:18 -070018import org.onlab.packet.MacAddress;
19import org.onlab.packet.VlanId;
20import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
alshabib6eb438a2014-10-01 16:39:37 -070021import org.projectfloodlight.openflow.protocol.OFFlowRemovedReason;
alshabib6b5cfec2014-09-18 17:42:18 -070022import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
23import org.projectfloodlight.openflow.protocol.action.OFAction;
24import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
25import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
26import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
27import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
28import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
29import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
30import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
31import org.projectfloodlight.openflow.protocol.match.Match;
32import org.projectfloodlight.openflow.protocol.match.MatchField;
33import org.projectfloodlight.openflow.types.IPv4Address;
34import org.slf4j.Logger;
35
36public class FlowRuleBuilder {
37 private final Logger log = getLogger(getClass());
38
39 private final OFFlowStatsEntry stat;
40 private final OFFlowRemoved removed;
41
42 private final Match match;
43 private final List<OFAction> actions;
44
45 private final Dpid dpid;
46
47
48
49
50 public FlowRuleBuilder(Dpid dpid, OFFlowStatsEntry entry) {
51 this.stat = entry;
52 this.match = entry.getMatch();
53 this.actions = entry.getActions();
54 this.dpid = dpid;
alshabib219ebaa2014-09-22 15:41:24 -070055 this.removed = null;
alshabib6b5cfec2014-09-18 17:42:18 -070056 }
57
58 public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) {
59 this.match = removed.getMatch();
60 this.removed = removed;
61
62 this.dpid = dpid;
63 this.actions = null;
64 this.stat = null;
65
66 }
67
68 public FlowRule build() {
69 if (stat != null) {
70 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
71 buildSelector(), buildTreatment(), stat.getPriority(),
alshabiba7f7ca82014-09-22 11:41:23 -070072 FlowRuleState.ADDED, stat.getDurationNsec() / 1000000,
alshabib6b5cfec2014-09-18 17:42:18 -070073 stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
alshabibba5ac482014-10-02 17:15:20 -070074 stat.getCookie().getValue(), false, stat.getIdleTimeout());
alshabib6b5cfec2014-09-18 17:42:18 -070075 } else {
76 // TODO: revisit potentially.
77 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
78 buildSelector(), null, removed.getPriority(),
alshabiba7f7ca82014-09-22 11:41:23 -070079 FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000,
alshabib6b5cfec2014-09-18 17:42:18 -070080 removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
alshabib6eb438a2014-10-01 16:39:37 -070081 removed.getCookie().getValue(),
alshabibba5ac482014-10-02 17:15:20 -070082 removed.getReason() == OFFlowRemovedReason.IDLE_TIMEOUT.ordinal(),
83 stat.getIdleTimeout());
alshabib6b5cfec2014-09-18 17:42:18 -070084 }
85 }
86
87
88 private TrafficTreatment buildTreatment() {
tom9a693fd2014-10-03 11:32:19 -070089 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
alshabib6b5cfec2014-09-18 17:42:18 -070090 // If this is a drop rule
91 if (actions.size() == 0) {
alshabib010c31d2014-09-26 10:01:12 -070092 builder.drop();
alshabib6b5cfec2014-09-18 17:42:18 -070093 return builder.build();
94 }
95 for (OFAction act : actions) {
96 switch (act.getType()) {
97 case OUTPUT:
98 OFActionOutput out = (OFActionOutput) act;
alshabib010c31d2014-09-26 10:01:12 -070099 builder.setOutput(
100 PortNumber.portNumber(out.getPort().getPortNumber()));
alshabib6b5cfec2014-09-18 17:42:18 -0700101 break;
102 case SET_VLAN_VID:
alshabib010c31d2014-09-26 10:01:12 -0700103 OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
104 builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan()));
105 break;
106 case SET_VLAN_PCP:
alshabib6b5cfec2014-09-18 17:42:18 -0700107 OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
alshabib010c31d2014-09-26 10:01:12 -0700108 builder.setVlanId(VlanId.vlanId(pcp.getVlanPcp().getValue()));
alshabib6b5cfec2014-09-18 17:42:18 -0700109 break;
110 case SET_DL_DST:
111 OFActionSetDlDst dldst = (OFActionSetDlDst) act;
alshabib010c31d2014-09-26 10:01:12 -0700112 builder.setEthDst(
113 MacAddress.valueOf(dldst.getDlAddr().getLong()));
alshabib6b5cfec2014-09-18 17:42:18 -0700114 break;
115 case SET_DL_SRC:
116 OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
alshabib010c31d2014-09-26 10:01:12 -0700117 builder.setEthSrc(
118 MacAddress.valueOf(dlsrc.getDlAddr().getLong()));
alshabib6b5cfec2014-09-18 17:42:18 -0700119
120 break;
121 case SET_NW_DST:
122 OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
123 IPv4Address di = nwdst.getNwAddr();
124 if (di.isCidrMask()) {
alshabib010c31d2014-09-26 10:01:12 -0700125 builder.setIpDst(IpPrefix.valueOf(di.getInt(),
126 di.asCidrMaskLength()));
alshabib6b5cfec2014-09-18 17:42:18 -0700127 } else {
alshabib010c31d2014-09-26 10:01:12 -0700128 builder.setIpDst(IpPrefix.valueOf(di.getInt()));
alshabib6b5cfec2014-09-18 17:42:18 -0700129 }
130 break;
131 case SET_NW_SRC:
132 OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
133 IPv4Address si = nwsrc.getNwAddr();
134 if (si.isCidrMask()) {
alshabib010c31d2014-09-26 10:01:12 -0700135 builder.setIpSrc(IpPrefix.valueOf(si.getInt(),
136 si.asCidrMaskLength()));
alshabib6b5cfec2014-09-18 17:42:18 -0700137 } else {
alshabib010c31d2014-09-26 10:01:12 -0700138 builder.setIpSrc(IpPrefix.valueOf(si.getInt()));
alshabib6b5cfec2014-09-18 17:42:18 -0700139 }
140 break;
141 case SET_TP_DST:
142 case SET_TP_SRC:
143 case POP_MPLS:
144 case POP_PBB:
145 case POP_VLAN:
146 case PUSH_MPLS:
147 case PUSH_PBB:
148 case PUSH_VLAN:
149 case SET_FIELD:
150 case SET_MPLS_LABEL:
151 case SET_MPLS_TC:
152 case SET_MPLS_TTL:
153 case SET_NW_ECN:
154 case SET_NW_TOS:
155 case SET_NW_TTL:
156 case SET_QUEUE:
157 case STRIP_VLAN:
158 case COPY_TTL_IN:
159 case COPY_TTL_OUT:
160 case DEC_MPLS_TTL:
161 case DEC_NW_TTL:
162 case ENQUEUE:
163 case EXPERIMENTER:
164 case GROUP:
165 default:
166 log.warn("Action type {} not yet implemented.", act.getType());
167 }
168 }
169
170 return builder.build();
171 }
172
173 private TrafficSelector buildSelector() {
tom9a693fd2014-10-03 11:32:19 -0700174 TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
alshabib6b5cfec2014-09-18 17:42:18 -0700175 for (MatchField<?> field : match.getMatchFields()) {
176 switch (field.id) {
177 case IN_PORT:
alshabib010c31d2014-09-26 10:01:12 -0700178 builder.matchInport(PortNumber
179 .portNumber(match.get(MatchField.IN_PORT).getPortNumber()));
alshabib6b5cfec2014-09-18 17:42:18 -0700180 break;
181 case ETH_SRC:
182 MacAddress sMac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
alshabib010c31d2014-09-26 10:01:12 -0700183 builder.matchEthSrc(sMac);
alshabib6b5cfec2014-09-18 17:42:18 -0700184 break;
185 case ETH_DST:
186 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
alshabib010c31d2014-09-26 10:01:12 -0700187 builder.matchEthDst(dMac);
alshabib6b5cfec2014-09-18 17:42:18 -0700188 break;
189 case ETH_TYPE:
190 int ethType = match.get(MatchField.ETH_TYPE).getValue();
alshabib010c31d2014-09-26 10:01:12 -0700191 builder.matchEthType((short) ethType);
alshabib6b5cfec2014-09-18 17:42:18 -0700192 break;
193 case IPV4_DST:
194 IPv4Address di = match.get(MatchField.IPV4_DST);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700195 IpPrefix dip;
alshabib6b5cfec2014-09-18 17:42:18 -0700196 if (di.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700197 dip = IpPrefix.valueOf(di.getInt(), di.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700198 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700199 dip = IpPrefix.valueOf(di.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700200 }
alshabib010c31d2014-09-26 10:01:12 -0700201 builder.matchIPDst(dip);
alshabib6b5cfec2014-09-18 17:42:18 -0700202 break;
203 case IPV4_SRC:
204 IPv4Address si = match.get(MatchField.IPV4_SRC);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700205 IpPrefix sip;
alshabib6b5cfec2014-09-18 17:42:18 -0700206 if (si.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700207 sip = IpPrefix.valueOf(si.getInt(), si.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700208 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700209 sip = IpPrefix.valueOf(si.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700210 }
alshabib010c31d2014-09-26 10:01:12 -0700211 builder.matchIPSrc(sip);
alshabib6b5cfec2014-09-18 17:42:18 -0700212 break;
213 case IP_PROTO:
214 short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
alshabib010c31d2014-09-26 10:01:12 -0700215 builder.matchIPProtocol((byte) proto);
alshabib6b5cfec2014-09-18 17:42:18 -0700216 break;
217 case VLAN_PCP:
218 byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
alshabib010c31d2014-09-26 10:01:12 -0700219 builder.matchVlanPcp(vlanPcp);
alshabib6b5cfec2014-09-18 17:42:18 -0700220 break;
221 case VLAN_VID:
222 VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
alshabib010c31d2014-09-26 10:01:12 -0700223 builder.matchVlanId(vlanId);
alshabib6b5cfec2014-09-18 17:42:18 -0700224 break;
225 case ARP_OP:
226 case ARP_SHA:
227 case ARP_SPA:
228 case ARP_THA:
229 case ARP_TPA:
230 case ICMPV4_CODE:
231 case ICMPV4_TYPE:
232 case ICMPV6_CODE:
233 case ICMPV6_TYPE:
234 case IN_PHY_PORT:
235 case IPV6_DST:
236 case IPV6_FLABEL:
237 case IPV6_ND_SLL:
238 case IPV6_ND_TARGET:
239 case IPV6_ND_TLL:
240 case IPV6_SRC:
241 case IP_DSCP:
242 case IP_ECN:
243 case METADATA:
244 case MPLS_LABEL:
245 case MPLS_TC:
246 case SCTP_DST:
247 case SCTP_SRC:
248 case TCP_DST:
249 case TCP_SRC:
250 case TUNNEL_ID:
251 case UDP_DST:
252 case UDP_SRC:
253 default:
254 log.warn("Match type {} not yet implemented.", field.id);
255
256
257 }
258 }
259 return builder.build();
260 }
261
262}