blob: ab01ab701e7b52a038cb80e66eaa5e382850b5a6 [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;
13import org.onlab.onos.net.flow.TrafficSelector;
14import org.onlab.onos.net.flow.TrafficTreatment;
15import org.onlab.onos.net.flow.criteria.Criteria;
16import org.onlab.onos.net.flow.instructions.Instructions;
17import org.onlab.onos.openflow.controller.Dpid;
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -070018import org.onlab.packet.IpPrefix;
alshabib6b5cfec2014-09-18 17:42:18 -070019import org.onlab.packet.MacAddress;
20import org.onlab.packet.VlanId;
21import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
22import 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;
55 removed = null;
56 }
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(),
72 stat.getDurationNsec() / 1000000, stat.getIdleTimeout(),
73 stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
74 (int) (stat.getCookie().getValue() & 0xFFFFFFFF));
75 } else {
76 // TODO: revisit potentially.
77 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
78 buildSelector(), null, removed.getPriority(),
79 removed.getDurationNsec() / 1000000, removed.getIdleTimeout(),
80 removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
81 (int) (removed.getCookie().getValue() & 0xFFFFFFFF));
82 }
83 }
84
85
86 private TrafficTreatment buildTreatment() {
87 TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
88 // If this is a drop rule
89 if (actions.size() == 0) {
90 builder.add(Instructions.createDrop());
91 return builder.build();
92 }
93 for (OFAction act : actions) {
94 switch (act.getType()) {
95 case OUTPUT:
96 OFActionOutput out = (OFActionOutput) act;
97 builder.add(Instructions.createOutput(
98 PortNumber.portNumber(out.getPort().getPortNumber())));
99 break;
100 case SET_VLAN_PCP:
101 OFActionSetVlanVid vlan = (OFActionSetVlanVid) act;
102 builder.add(Instructions.modVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan())));
103 break;
104 case SET_VLAN_VID:
105 OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act;
106 builder.add(Instructions.modVlanId(VlanId.vlanId(pcp.getVlanPcp().getValue())));
107 break;
108 case SET_DL_DST:
109 OFActionSetDlDst dldst = (OFActionSetDlDst) act;
110 builder.add(Instructions.modL2Dst(
111 MacAddress.valueOf(dldst.getDlAddr().getLong())));
112 break;
113 case SET_DL_SRC:
114 OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act;
115 builder.add(Instructions.modL2Src(
116 MacAddress.valueOf(dlsrc.getDlAddr().getLong())));
117
118 break;
119 case SET_NW_DST:
120 OFActionSetNwDst nwdst = (OFActionSetNwDst) act;
121 IPv4Address di = nwdst.getNwAddr();
122 if (di.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700123 builder.add(Instructions.modL3Dst(IpPrefix.valueOf(di.getInt(),
alshabib6b5cfec2014-09-18 17:42:18 -0700124 di.asCidrMaskLength())));
125 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700126 builder.add(Instructions.modL3Dst(IpPrefix.valueOf(di.getInt())));
alshabib6b5cfec2014-09-18 17:42:18 -0700127 }
128 break;
129 case SET_NW_SRC:
130 OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act;
131 IPv4Address si = nwsrc.getNwAddr();
132 if (si.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700133 builder.add(Instructions.modL3Dst(IpPrefix.valueOf(si.getInt(),
alshabib6b5cfec2014-09-18 17:42:18 -0700134 si.asCidrMaskLength())));
135 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700136 builder.add(Instructions.modL3Dst(IpPrefix.valueOf(si.getInt())));
alshabib6b5cfec2014-09-18 17:42:18 -0700137 }
138 break;
139 case SET_TP_DST:
140 case SET_TP_SRC:
141 case POP_MPLS:
142 case POP_PBB:
143 case POP_VLAN:
144 case PUSH_MPLS:
145 case PUSH_PBB:
146 case PUSH_VLAN:
147 case SET_FIELD:
148 case SET_MPLS_LABEL:
149 case SET_MPLS_TC:
150 case SET_MPLS_TTL:
151 case SET_NW_ECN:
152 case SET_NW_TOS:
153 case SET_NW_TTL:
154 case SET_QUEUE:
155 case STRIP_VLAN:
156 case COPY_TTL_IN:
157 case COPY_TTL_OUT:
158 case DEC_MPLS_TTL:
159 case DEC_NW_TTL:
160 case ENQUEUE:
161 case EXPERIMENTER:
162 case GROUP:
163 default:
164 log.warn("Action type {} not yet implemented.", act.getType());
165 }
166 }
167
168 return builder.build();
169 }
170
171 private TrafficSelector buildSelector() {
172 TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder();
173 for (MatchField<?> field : match.getMatchFields()) {
174 switch (field.id) {
175 case IN_PORT:
176 builder.add(Criteria.matchInPort(PortNumber
177 .portNumber(match.get(MatchField.IN_PORT).getPortNumber())));
178 break;
179 case ETH_SRC:
180 MacAddress sMac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
181 builder.add(Criteria.matchEthSrc(sMac));
182 break;
183 case ETH_DST:
184 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
185 builder.add(Criteria.matchEthSrc(dMac));
186 break;
187 case ETH_TYPE:
188 int ethType = match.get(MatchField.ETH_TYPE).getValue();
189 builder.add(Criteria.matchEthType((short) ethType));
190 break;
191 case IPV4_DST:
192 IPv4Address di = match.get(MatchField.IPV4_DST);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700193 IpPrefix dip;
alshabib6b5cfec2014-09-18 17:42:18 -0700194 if (di.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700195 dip = IpPrefix.valueOf(di.getInt(), di.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700196 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700197 dip = IpPrefix.valueOf(di.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700198 }
199 builder.add(Criteria.matchIPDst(dip));
200 break;
201 case IPV4_SRC:
202 IPv4Address si = match.get(MatchField.IPV4_SRC);
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700203 IpPrefix sip;
alshabib6b5cfec2014-09-18 17:42:18 -0700204 if (si.isCidrMask()) {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700205 sip = IpPrefix.valueOf(si.getInt(), si.asCidrMaskLength());
alshabib6b5cfec2014-09-18 17:42:18 -0700206 } else {
Ayaka Koshibe1d56fe42014-09-19 16:51:58 -0700207 sip = IpPrefix.valueOf(si.getInt());
alshabib6b5cfec2014-09-18 17:42:18 -0700208 }
209 builder.add(Criteria.matchIPSrc(sip));
210 break;
211 case IP_PROTO:
212 short proto = match.get(MatchField.IP_PROTO).getIpProtocolNumber();
213 builder.add(Criteria.matchIPProtocol((byte) proto));
214 break;
215 case VLAN_PCP:
216 byte vlanPcp = match.get(MatchField.VLAN_PCP).getValue();
217 builder.add(Criteria.matchVlanPcp(vlanPcp));
218 break;
219 case VLAN_VID:
220 VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
221 builder.add(Criteria.matchVlanId(vlanId));
222 break;
223 case ARP_OP:
224 case ARP_SHA:
225 case ARP_SPA:
226 case ARP_THA:
227 case ARP_TPA:
228 case ICMPV4_CODE:
229 case ICMPV4_TYPE:
230 case ICMPV6_CODE:
231 case ICMPV6_TYPE:
232 case IN_PHY_PORT:
233 case IPV6_DST:
234 case IPV6_FLABEL:
235 case IPV6_ND_SLL:
236 case IPV6_ND_TARGET:
237 case IPV6_ND_TLL:
238 case IPV6_SRC:
239 case IP_DSCP:
240 case IP_ECN:
241 case METADATA:
242 case MPLS_LABEL:
243 case MPLS_TC:
244 case SCTP_DST:
245 case SCTP_SRC:
246 case TCP_DST:
247 case TCP_SRC:
248 case TUNNEL_ID:
249 case UDP_DST:
250 case UDP_SRC:
251 default:
252 log.warn("Match type {} not yet implemented.", field.id);
253
254
255 }
256 }
257 return builder.build();
258 }
259
260}