blob: ac00f05dfa95f5ae067b2fa3ed260277d64db326 [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(),
alshabib6eb438a2014-10-01 16:39:37 -070074 stat.getCookie().getValue(), false);
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(),
82 removed.getReason() == OFFlowRemovedReason.IDLE_TIMEOUT.ordinal());
alshabib6b5cfec2014-09-18 17:42:18 -070083 }
84 }
85
86
87 private TrafficTreatment buildTreatment() {
88 TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
89 // If this is a drop rule
90 if (actions.size() == 0) {
alshabib010c31d2014-09-26 10:01:12 -070091 builder.drop();
alshabib6b5cfec2014-09-18 17:42:18 -070092 return builder.build();
93 }
94 for (OFAction act : actions) {
95 switch (act.getType()) {
96 case OUTPUT:
97 OFActionOutput out = (OFActionOutput) act;
alshabib010c31d2014-09-26 10:01:12 -070098 builder.setOutput(
99 PortNumber.portNumber(out.getPort().getPortNumber()));
alshabib6b5cfec2014-09-18 17:42:18 -0700100 break;
101 case SET_VLAN_VID:
alshabib010c31d2014-09-26 10:01:12 -0700102 OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
103 builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan()));
104 break;
105 case SET_VLAN_PCP:
alshabib6b5cfec2014-09-18 17:42:18 -0700106 OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
alshabib010c31d2014-09-26 10:01:12 -0700107 builder.setVlanId(VlanId.vlanId(pcp.getVlanPcp().getValue()));
alshabib6b5cfec2014-09-18 17:42:18 -0700108 break;
109 case SET_DL_DST:
110 OFActionSetDlDst dldst = (OFActionSetDlDst) act;
alshabib010c31d2014-09-26 10:01:12 -0700111 builder.setEthDst(
112 MacAddress.valueOf(dldst.getDlAddr().getLong()));
alshabib6b5cfec2014-09-18 17:42:18 -0700113 break;
114 case SET_DL_SRC:
115 OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
alshabib010c31d2014-09-26 10:01:12 -0700116 builder.setEthSrc(
117 MacAddress.valueOf(dlsrc.getDlAddr().getLong()));
alshabib6b5cfec2014-09-18 17:42:18 -0700118
119 break;
120 case SET_NW_DST:
121 OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
122 IPv4Address di = nwdst.getNwAddr();
123 if (di.isCidrMask()) {
alshabib010c31d2014-09-26 10:01:12 -0700124 builder.setIpDst(IpPrefix.valueOf(di.getInt(),
125 di.asCidrMaskLength()));
alshabib6b5cfec2014-09-18 17:42:18 -0700126 } else {
alshabib010c31d2014-09-26 10:01:12 -0700127 builder.setIpDst(IpPrefix.valueOf(di.getInt()));
alshabib6b5cfec2014-09-18 17:42:18 -0700128 }
129 break;
130 case SET_NW_SRC:
131 OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
132 IPv4Address si = nwsrc.getNwAddr();
133 if (si.isCidrMask()) {
alshabib010c31d2014-09-26 10:01:12 -0700134 builder.setIpSrc(IpPrefix.valueOf(si.getInt(),
135 si.asCidrMaskLength()));
alshabib6b5cfec2014-09-18 17:42:18 -0700136 } else {
alshabib010c31d2014-09-26 10:01:12 -0700137 builder.setIpSrc(IpPrefix.valueOf(si.getInt()));
alshabib6b5cfec2014-09-18 17:42:18 -0700138 }
139 break;
140 case SET_TP_DST:
141 case SET_TP_SRC:
142 case POP_MPLS:
143 case POP_PBB:
144 case POP_VLAN:
145 case PUSH_MPLS:
146 case PUSH_PBB:
147 case PUSH_VLAN:
148 case SET_FIELD:
149 case SET_MPLS_LABEL:
150 case SET_MPLS_TC:
151 case SET_MPLS_TTL:
152 case SET_NW_ECN:
153 case SET_NW_TOS:
154 case SET_NW_TTL:
155 case SET_QUEUE:
156 case STRIP_VLAN:
157 case COPY_TTL_IN:
158 case COPY_TTL_OUT:
159 case DEC_MPLS_TTL:
160 case DEC_NW_TTL:
161 case ENQUEUE:
162 case EXPERIMENTER:
163 case GROUP:
164 default:
165 log.warn("Action type {} not yet implemented.", act.getType());
166 }
167 }
168
169 return builder.build();
170 }
171
172 private TrafficSelector buildSelector() {
173 TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder();
174 for (MatchField<?> field : match.getMatchFields()) {
175 switch (field.id) {
176 case IN_PORT:
alshabib010c31d2014-09-26 10:01:12 -0700177 builder.matchInport(PortNumber
178 .portNumber(match.get(MatchField.IN_PORT).getPortNumber()));
alshabib6b5cfec2014-09-18 17:42:18 -0700179 break;
180 case ETH_SRC:
181 MacAddress sMac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
alshabib010c31d2014-09-26 10:01:12 -0700182 builder.matchEthSrc(sMac);
alshabib6b5cfec2014-09-18 17:42:18 -0700183 break;
184 case ETH_DST:
185 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
alshabib010c31d2014-09-26 10:01:12 -0700186 builder.matchEthDst(dMac);
alshabib6b5cfec2014-09-18 17:42:18 -0700187 break;
188 case ETH_TYPE:
189 int ethType = match.get(MatchField.ETH_TYPE).getValue();
alshabib010c31d2014-09-26 10:01:12 -0700190 builder.matchEthType((short) ethType);
alshabib6b5cfec2014-09-18 17:42:18 -0700191 break;
192 case IPV4_DST:
193 IPv4Address di = match.get(MatchField.IPV4_DST);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700194 IpPrefix dip;
alshabib6b5cfec2014-09-18 17:42:18 -0700195 if (di.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700196 dip = IpPrefix.valueOf(di.getInt(), di.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700197 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700198 dip = IpPrefix.valueOf(di.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700199 }
alshabib010c31d2014-09-26 10:01:12 -0700200 builder.matchIPDst(dip);
alshabib6b5cfec2014-09-18 17:42:18 -0700201 break;
202 case IPV4_SRC:
203 IPv4Address si = match.get(MatchField.IPV4_SRC);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700204 IpPrefix sip;
alshabib6b5cfec2014-09-18 17:42:18 -0700205 if (si.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700206 sip = IpPrefix.valueOf(si.getInt(), si.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700207 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700208 sip = IpPrefix.valueOf(si.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700209 }
alshabib010c31d2014-09-26 10:01:12 -0700210 builder.matchIPSrc(sip);
alshabib6b5cfec2014-09-18 17:42:18 -0700211 break;
212 case IP_PROTO:
213 short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
alshabib010c31d2014-09-26 10:01:12 -0700214 builder.matchIPProtocol((byte) proto);
alshabib6b5cfec2014-09-18 17:42:18 -0700215 break;
216 case VLAN_PCP:
217 byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
alshabib010c31d2014-09-26 10:01:12 -0700218 builder.matchVlanPcp(vlanPcp);
alshabib6b5cfec2014-09-18 17:42:18 -0700219 break;
220 case VLAN_VID:
221 VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
alshabib010c31d2014-09-26 10:01:12 -0700222 builder.matchVlanId(vlanId);
alshabib6b5cfec2014-09-18 17:42:18 -0700223 break;
224 case ARP_OP:
225 case ARP_SHA:
226 case ARP_SPA:
227 case ARP_THA:
228 case ARP_TPA:
229 case ICMPV4_CODE:
230 case ICMPV4_TYPE:
231 case ICMPV6_CODE:
232 case ICMPV6_TYPE:
233 case IN_PHY_PORT:
234 case IPV6_DST:
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_LABEL:
244 case MPLS_TC:
245 case SCTP_DST:
246 case SCTP_SRC:
247 case TCP_DST:
248 case TCP_SRC:
249 case TUNNEL_ID:
250 case UDP_DST:
251 case UDP_SRC:
252 default:
253 log.warn("Match type {} not yet implemented.", field.id);
254
255
256 }
257 }
258 return builder.build();
259 }
260
261}