blob: 39540d7fcf4bfbd34781f832f217e2780acf3d48 [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;
16import org.onlab.onos.net.flow.criteria.Criteria;
17import org.onlab.onos.net.flow.instructions.Instructions;
18import org.onlab.onos.openflow.controller.Dpid;
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070019import org.onlab.packet.IpPrefix;
alshabib6b5cfec2014-09-18 17:42:18 -070020import org.onlab.packet.MacAddress;
21import org.onlab.packet.VlanId;
22import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
23import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
24import org.projectfloodlight.openflow.protocol.action.OFAction;
25import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
26import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
27import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
28import org.projectfloodlight.openflow.protocol.action.OFActionSetNwDst;
29import org.projectfloodlight.openflow.protocol.action.OFActionSetNwSrc;
30import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp;
31import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid;
32import org.projectfloodlight.openflow.protocol.match.Match;
33import org.projectfloodlight.openflow.protocol.match.MatchField;
34import org.projectfloodlight.openflow.types.IPv4Address;
35import org.slf4j.Logger;
36
37public class FlowRuleBuilder {
38 private final Logger log = getLogger(getClass());
39
40 private final OFFlowStatsEntry stat;
41 private final OFFlowRemoved removed;
42
43 private final Match match;
44 private final List<OFAction> actions;
45
46 private final Dpid dpid;
47
48
49
50
51 public FlowRuleBuilder(Dpid dpid, OFFlowStatsEntry entry) {
52 this.stat = entry;
53 this.match = entry.getMatch();
54 this.actions = entry.getActions();
55 this.dpid = dpid;
alshabib219ebaa2014-09-22 15:41:24 -070056 this.removed = null;
alshabib6b5cfec2014-09-18 17:42:18 -070057 }
58
59 public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) {
60 this.match = removed.getMatch();
61 this.removed = removed;
62
63 this.dpid = dpid;
64 this.actions = null;
65 this.stat = null;
66
67 }
68
69 public FlowRule build() {
70 if (stat != null) {
71 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
72 buildSelector(), buildTreatment(), stat.getPriority(),
alshabiba7f7ca82014-09-22 11:41:23 -070073 FlowRuleState.ADDED, stat.getDurationNsec() / 1000000,
alshabib6b5cfec2014-09-18 17:42:18 -070074 stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
alshabib219ebaa2014-09-22 15:41:24 -070075 stat.getCookie().getValue());
alshabib6b5cfec2014-09-18 17:42:18 -070076 } else {
77 // TODO: revisit potentially.
78 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
79 buildSelector(), null, removed.getPriority(),
alshabiba7f7ca82014-09-22 11:41:23 -070080 FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000,
alshabib6b5cfec2014-09-18 17:42:18 -070081 removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
alshabib219ebaa2014-09-22 15:41:24 -070082 removed.getCookie().getValue());
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) {
91 builder.add(Instructions.createDrop());
92 return builder.build();
93 }
94 for (OFAction act : actions) {
95 switch (act.getType()) {
96 case OUTPUT:
97 OFActionOutput out = (OFActionOutput) act;
98 builder.add(Instructions.createOutput(
99 PortNumber.portNumber(out.getPort().getPortNumber())));
100 break;
101 case SET_VLAN_PCP:
102 OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
103 builder.add(Instructions.modVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan())));
104 break;
105 case SET_VLAN_VID:
106 OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
107 builder.add(Instructions.modVlanId(VlanId.vlanId(pcp.getVlanPcp().getValue())));
108 break;
109 case SET_DL_DST:
110 OFActionSetDlDst dldst = (OFActionSetDlDst) act;
111 builder.add(Instructions.modL2Dst(
112 MacAddress.valueOf(dldst.getDlAddr().getLong())));
113 break;
114 case SET_DL_SRC:
115 OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
116 builder.add(Instructions.modL2Src(
117 MacAddress.valueOf(dlsrc.getDlAddr().getLong())));
118
119 break;
120 case SET_NW_DST:
121 OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
122 IPv4Address di = nwdst.getNwAddr();
123 if (di.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700124 builder.add(Instructions.modL3Dst(IpPrefix.valueOf(di.getInt(),
alshabib6b5cfec2014-09-18 17:42:18 -0700125 di.asCidrMaskLength())));
126 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700127 builder.add(Instructions.modL3Dst(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()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700134 builder.add(Instructions.modL3Dst(IpPrefix.valueOf(si.getInt(),
alshabib6b5cfec2014-09-18 17:42:18 -0700135 si.asCidrMaskLength())));
136 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700137 builder.add(Instructions.modL3Dst(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:
177 builder.add(Criteria.matchInPort(PortNumber
178 .portNumber(match.get(MatchField.IN_PORT).getPortNumber())));
179 break;
180 case ETH_SRC:
181 MacAddress sMac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
182 builder.add(Criteria.matchEthSrc(sMac));
183 break;
184 case ETH_DST:
185 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
alshabiba68eb962014-09-24 20:34:13 -0700186 builder.add(Criteria.matchEthDst(dMac));
alshabib6b5cfec2014-09-18 17:42:18 -0700187 break;
188 case ETH_TYPE:
189 int ethType = match.get(MatchField.ETH_TYPE).getValue();
190 builder.add(Criteria.matchEthType((short) ethType));
191 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 }
200 builder.add(Criteria.matchIPDst(dip));
201 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 }
210 builder.add(Criteria.matchIPSrc(sip));
211 break;
212 case IP_PROTO:
213 short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
214 builder.add(Criteria.matchIPProtocol((byte) proto));
215 break;
216 case VLAN_PCP:
217 byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
218 builder.add(Criteria.matchVlanPcp(vlanPcp));
219 break;
220 case VLAN_VID:
221 VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
222 builder.add(Criteria.matchVlanId(vlanId));
223 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}