blob: 6d773de654a92af45650ce272b2dbe7a0db7f5d2 [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;
21import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
22import org.projectfloodlight.openflow.protocol.action.OFAction;
23import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
24import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
25import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
26import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
27import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
28import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
29import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
30import org.projectfloodlight.openflow.protocol.match.Match;
31import org.projectfloodlight.openflow.protocol.match.MatchField;
32import org.projectfloodlight.openflow.types.IPv4Address;
33import org.slf4j.Logger;
34
35public class FlowRuleBuilder {
36 private final Logger log = getLogger(getClass());
37
38 private final OFFlowStatsEntry stat;
39 private final OFFlowRemoved removed;
40
41 private final Match match;
42 private final List<OFAction> actions;
43
44 private final Dpid dpid;
45
46
47
48
49 public FlowRuleBuilder(Dpid dpid, OFFlowStatsEntry entry) {
50 this.stat = entry;
51 this.match = entry.getMatch();
52 this.actions = entry.getActions();
53 this.dpid = dpid;
alshabib219ebaa2014-09-22 15:41:24 -070054 this.removed = null;
alshabib6b5cfec2014-09-18 17:42:18 -070055 }
56
57 public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) {
58 this.match = removed.getMatch();
59 this.removed = removed;
60
61 this.dpid = dpid;
62 this.actions = null;
63 this.stat = null;
64
65 }
66
67 public FlowRule build() {
68 if (stat != null) {
69 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
70 buildSelector(), buildTreatment(), stat.getPriority(),
alshabiba7f7ca82014-09-22 11:41:23 -070071 FlowRuleState.ADDED, stat.getDurationNsec() / 1000000,
alshabib6b5cfec2014-09-18 17:42:18 -070072 stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
alshabib219ebaa2014-09-22 15:41:24 -070073 stat.getCookie().getValue());
alshabib6b5cfec2014-09-18 17:42:18 -070074 } else {
75 // TODO: revisit potentially.
76 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
77 buildSelector(), null, removed.getPriority(),
alshabiba7f7ca82014-09-22 11:41:23 -070078 FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000,
alshabib6b5cfec2014-09-18 17:42:18 -070079 removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
alshabib219ebaa2014-09-22 15:41:24 -070080 removed.getCookie().getValue());
alshabib6b5cfec2014-09-18 17:42:18 -070081 }
82 }
83
84
85 private TrafficTreatment buildTreatment() {
86 TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
87 // If this is a drop rule
88 if (actions.size() == 0) {
alshabib010c31d2014-09-26 10:01:12 -070089 builder.drop();
alshabib6b5cfec2014-09-18 17:42:18 -070090 return builder.build();
91 }
92 for (OFAction act : actions) {
93 switch (act.getType()) {
94 case OUTPUT:
95 OFActionOutput out = (OFActionOutput) act;
alshabib010c31d2014-09-26 10:01:12 -070096 builder.setOutput(
97 PortNumber.portNumber(out.getPort().getPortNumber()));
alshabib6b5cfec2014-09-18 17:42:18 -070098 break;
99 case SET_VLAN_VID:
alshabib010c31d2014-09-26 10:01:12 -0700100 OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
101 builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan()));
102 break;
103 case SET_VLAN_PCP:
alshabib6b5cfec2014-09-18 17:42:18 -0700104 OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
alshabib010c31d2014-09-26 10:01:12 -0700105 builder.setVlanId(VlanId.vlanId(pcp.getVlanPcp().getValue()));
alshabib6b5cfec2014-09-18 17:42:18 -0700106 break;
107 case SET_DL_DST:
108 OFActionSetDlDst dldst = (OFActionSetDlDst) act;
alshabib010c31d2014-09-26 10:01:12 -0700109 builder.setEthDst(
110 MacAddress.valueOf(dldst.getDlAddr().getLong()));
alshabib6b5cfec2014-09-18 17:42:18 -0700111 break;
112 case SET_DL_SRC:
113 OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
alshabib010c31d2014-09-26 10:01:12 -0700114 builder.setEthSrc(
115 MacAddress.valueOf(dlsrc.getDlAddr().getLong()));
alshabib6b5cfec2014-09-18 17:42:18 -0700116
117 break;
118 case SET_NW_DST:
119 OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
120 IPv4Address di = nwdst.getNwAddr();
121 if (di.isCidrMask()) {
alshabib010c31d2014-09-26 10:01:12 -0700122 builder.setIpDst(IpPrefix.valueOf(di.getInt(),
123 di.asCidrMaskLength()));
alshabib6b5cfec2014-09-18 17:42:18 -0700124 } else {
alshabib010c31d2014-09-26 10:01:12 -0700125 builder.setIpDst(IpPrefix.valueOf(di.getInt()));
alshabib6b5cfec2014-09-18 17:42:18 -0700126 }
127 break;
128 case SET_NW_SRC:
129 OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
130 IPv4Address si = nwsrc.getNwAddr();
131 if (si.isCidrMask()) {
alshabib010c31d2014-09-26 10:01:12 -0700132 builder.setIpSrc(IpPrefix.valueOf(si.getInt(),
133 si.asCidrMaskLength()));
alshabib6b5cfec2014-09-18 17:42:18 -0700134 } else {
alshabib010c31d2014-09-26 10:01:12 -0700135 builder.setIpSrc(IpPrefix.valueOf(si.getInt()));
alshabib6b5cfec2014-09-18 17:42:18 -0700136 }
137 break;
138 case SET_TP_DST:
139 case SET_TP_SRC:
140 case POP_MPLS:
141 case POP_PBB:
142 case POP_VLAN:
143 case PUSH_MPLS:
144 case PUSH_PBB:
145 case PUSH_VLAN:
146 case SET_FIELD:
147 case SET_MPLS_LABEL:
148 case SET_MPLS_TC:
149 case SET_MPLS_TTL:
150 case SET_NW_ECN:
151 case SET_NW_TOS:
152 case SET_NW_TTL:
153 case SET_QUEUE:
154 case STRIP_VLAN:
155 case COPY_TTL_IN:
156 case COPY_TTL_OUT:
157 case DEC_MPLS_TTL:
158 case DEC_NW_TTL:
159 case ENQUEUE:
160 case EXPERIMENTER:
161 case GROUP:
162 default:
163 log.warn("Action type {} not yet implemented.", act.getType());
164 }
165 }
166
167 return builder.build();
168 }
169
170 private TrafficSelector buildSelector() {
171 TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder();
172 for (MatchField<?> field : match.getMatchFields()) {
173 switch (field.id) {
174 case IN_PORT:
alshabib010c31d2014-09-26 10:01:12 -0700175 builder.matchInport(PortNumber
176 .portNumber(match.get(MatchField.IN_PORT).getPortNumber()));
alshabib6b5cfec2014-09-18 17:42:18 -0700177 break;
178 case ETH_SRC:
179 MacAddress sMac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
alshabib010c31d2014-09-26 10:01:12 -0700180 builder.matchEthSrc(sMac);
alshabib6b5cfec2014-09-18 17:42:18 -0700181 break;
182 case ETH_DST:
183 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
alshabib010c31d2014-09-26 10:01:12 -0700184 builder.matchEthDst(dMac);
alshabib6b5cfec2014-09-18 17:42:18 -0700185 break;
186 case ETH_TYPE:
187 int ethType = match.get(MatchField.ETH_TYPE).getValue();
alshabib010c31d2014-09-26 10:01:12 -0700188 builder.matchEthType((short) ethType);
alshabib6b5cfec2014-09-18 17:42:18 -0700189 break;
190 case IPV4_DST:
191 IPv4Address di = match.get(MatchField.IPV4_DST);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700192 IpPrefix dip;
alshabib6b5cfec2014-09-18 17:42:18 -0700193 if (di.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700194 dip = IpPrefix.valueOf(di.getInt(), di.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700195 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700196 dip = IpPrefix.valueOf(di.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700197 }
alshabib010c31d2014-09-26 10:01:12 -0700198 builder.matchIPDst(dip);
alshabib6b5cfec2014-09-18 17:42:18 -0700199 break;
200 case IPV4_SRC:
201 IPv4Address si = match.get(MatchField.IPV4_SRC);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700202 IpPrefix sip;
alshabib6b5cfec2014-09-18 17:42:18 -0700203 if (si.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700204 sip = IpPrefix.valueOf(si.getInt(), si.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700205 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700206 sip = IpPrefix.valueOf(si.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700207 }
alshabib010c31d2014-09-26 10:01:12 -0700208 builder.matchIPSrc(sip);
alshabib6b5cfec2014-09-18 17:42:18 -0700209 break;
210 case IP_PROTO:
211 short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
alshabib010c31d2014-09-26 10:01:12 -0700212 builder.matchIPProtocol((byte) proto);
alshabib6b5cfec2014-09-18 17:42:18 -0700213 break;
214 case VLAN_PCP:
215 byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
alshabib010c31d2014-09-26 10:01:12 -0700216 builder.matchVlanPcp(vlanPcp);
alshabib6b5cfec2014-09-18 17:42:18 -0700217 break;
218 case VLAN_VID:
219 VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
alshabib010c31d2014-09-26 10:01:12 -0700220 builder.matchVlanId(vlanId);
alshabib6b5cfec2014-09-18 17:42:18 -0700221 break;
222 case ARP_OP:
223 case ARP_SHA:
224 case ARP_SPA:
225 case ARP_THA:
226 case ARP_TPA:
227 case ICMPV4_CODE:
228 case ICMPV4_TYPE:
229 case ICMPV6_CODE:
230 case ICMPV6_TYPE:
231 case IN_PHY_PORT:
232 case IPV6_DST:
233 case IPV6_FLABEL:
234 case IPV6_ND_SLL:
235 case IPV6_ND_TARGET:
236 case IPV6_ND_TLL:
237 case IPV6_SRC:
238 case IP_DSCP:
239 case IP_ECN:
240 case METADATA:
241 case MPLS_LABEL:
242 case MPLS_TC:
243 case SCTP_DST:
244 case SCTP_SRC:
245 case TCP_DST:
246 case TCP_SRC:
247 case TUNNEL_ID:
248 case UDP_DST:
249 case UDP_SRC:
250 default:
251 log.warn("Match type {} not yet implemented.", field.id);
252
253
254 }
255 }
256 return builder.build();
257 }
258
259}