blob: 9a11a36f7adcd5f31ea5bc35789fd389444dbe3c [file] [log] [blame]
alshabib1cc04f72014-09-16 16:09:58 -07001package org.onlab.onos.provider.of.flow.impl;
2
3import static org.slf4j.LoggerFactory.getLogger;
4
alshabib35edb1a2014-09-16 17:44:44 -07005import java.util.Collections;
6import java.util.LinkedList;
7import java.util.List;
8
alshabib1cc04f72014-09-16 16:09:58 -07009import org.apache.felix.scr.annotations.Activate;
10import org.apache.felix.scr.annotations.Component;
11import org.apache.felix.scr.annotations.Deactivate;
12import org.apache.felix.scr.annotations.Reference;
13import org.apache.felix.scr.annotations.ReferenceCardinality;
14import org.onlab.onos.net.DeviceId;
15import org.onlab.onos.net.flow.FlowEntry;
16import org.onlab.onos.net.flow.FlowRule;
17import org.onlab.onos.net.flow.FlowRuleProvider;
18import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
19import org.onlab.onos.net.flow.FlowRuleProviderService;
alshabib35edb1a2014-09-16 17:44:44 -070020import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
21import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
22import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
23import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
24import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
25import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
26import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
27import org.onlab.onos.net.flow.criteria.Criterion;
28import org.onlab.onos.net.flow.instructions.Instruction;
29import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
30import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
31import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
32import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
33import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
34import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
alshabib1cc04f72014-09-16 16:09:58 -070035import org.onlab.onos.net.provider.AbstractProvider;
36import org.onlab.onos.net.provider.ProviderId;
37import org.onlab.onos.net.topology.TopologyService;
alshabib35edb1a2014-09-16 17:44:44 -070038import org.onlab.onos.of.controller.Dpid;
alshabib1cc04f72014-09-16 16:09:58 -070039import org.onlab.onos.of.controller.OpenFlowController;
alshabib35edb1a2014-09-16 17:44:44 -070040import org.onlab.onos.of.controller.OpenFlowSwitch;
41import org.projectfloodlight.openflow.protocol.OFFactory;
42import org.projectfloodlight.openflow.protocol.OFFlowMod;
43import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
44import org.projectfloodlight.openflow.protocol.action.OFAction;
45import org.projectfloodlight.openflow.protocol.match.Match;
46import org.projectfloodlight.openflow.protocol.match.MatchField;
47import org.projectfloodlight.openflow.types.EthType;
48import org.projectfloodlight.openflow.types.IPv4Address;
49import org.projectfloodlight.openflow.types.IpProtocol;
50import org.projectfloodlight.openflow.types.MacAddress;
alshabibf1cd8792014-09-16 18:04:18 -070051import org.projectfloodlight.openflow.types.OFBufferId;
alshabib35edb1a2014-09-16 17:44:44 -070052import org.projectfloodlight.openflow.types.OFPort;
53import org.projectfloodlight.openflow.types.OFVlanVidMatch;
54import org.projectfloodlight.openflow.types.VlanPcp;
55import org.projectfloodlight.openflow.types.VlanVid;
alshabib1cc04f72014-09-16 16:09:58 -070056import org.slf4j.Logger;
57
58/**
59 * Provider which uses an OpenFlow controller to detect network
60 * end-station hosts.
61 */
62@Component(immediate = true)
63public class OpenFlowRuleProvider extends AbstractProvider implements FlowRuleProvider {
64
65 private final Logger log = getLogger(getClass());
66
67 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 protected FlowRuleProviderRegistry providerRegistry;
69
70 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
71 protected OpenFlowController controller;
72
73 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
74 protected TopologyService topologyService;
75
76 private FlowRuleProviderService providerService;
77
78 /**
79 * Creates an OpenFlow host provider.
80 */
81 public OpenFlowRuleProvider() {
82 super(new ProviderId("org.onlab.onos.provider.openflow"));
83 }
84
85 @Activate
86 public void activate() {
87 providerService = providerRegistry.register(this);
88 log.info("Started");
89 }
90
91 @Deactivate
92 public void deactivate() {
93 providerRegistry.unregister(this);
94 providerService = null;
95
96 log.info("Stopped");
97 }
98 @Override
99 public void applyFlowRule(FlowRule... flowRules) {
alshabib35edb1a2014-09-16 17:44:44 -0700100 for (int i = 0; i < flowRules.length; i++) {
101 applyRule(flowRules[i]);
102 }
alshabib1cc04f72014-09-16 16:09:58 -0700103
104 }
105
alshabib35edb1a2014-09-16 17:44:44 -0700106 private void applyRule(FlowRule flowRule) {
107 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
108 Match match = buildMatch(flowRule.selector().criteria(), sw.factory());
109 List<OFAction> actions =
110 buildActions(flowRule.treatment().instructions(), sw.factory());
111
112 //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
113 OFFlowMod fm = sw.factory().buildFlowModify()
alshabibf1cd8792014-09-16 18:04:18 -0700114 .setBufferId(OFBufferId.NO_BUFFER)
alshabib35edb1a2014-09-16 17:44:44 -0700115 .setActions(actions)
116 .setMatch(match)
117 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
118 .setIdleTimeout(10)
119 .setHardTimeout(10)
120 .setPriority(flowRule.priority())
121 .build();
122
123 sw.sendMsg(fm);
124
125 }
126
127 private List<OFAction> buildActions(List<Instruction> instructions, OFFactory factory) {
128 List<OFAction> acts = new LinkedList<>();
129 for (Instruction i : instructions) {
130 switch (i.type()) {
131 case DROP:
132 log.warn("Saw drop action; assigning drop action");
alshabibf1cd8792014-09-16 18:04:18 -0700133 return new LinkedList<>();
alshabib35edb1a2014-09-16 17:44:44 -0700134 case L2MODIFICATION:
135 acts.add(buildL2Modification(i, factory));
136 case L3MODIFICATION:
137 acts.add(buildL3Modification(i, factory));
138 case OUTPUT:
139 break;
140 case GROUP:
141 default:
142 log.warn("Instruction type {} not yet implemented.", i.type());
143 }
144 }
145
146 return acts;
147 }
148
149 private OFAction buildL3Modification(Instruction i, OFFactory factory) {
150 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
151 ModIPInstruction ip;
152 switch (l3m.subtype()) {
153 case L3_DST:
154 ip = (ModIPInstruction) i;
155 return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
156 case L3_SRC:
157 ip = (ModIPInstruction) i;
158 return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
159 default:
160 log.warn("Unimplemented action type {}.", l3m.subtype());
161 break;
162 }
163 return null;
164 }
165
166 private OFAction buildL2Modification(Instruction i, OFFactory factory) {
167 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
168 ModEtherInstruction eth;
169 switch (l2m.subtype()) {
170 case L2_DST:
171 eth = (ModEtherInstruction) l2m;
172 return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
173 case L2_SRC:
174 eth = (ModEtherInstruction) l2m;
175 return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
176 case VLAN_ID:
177 ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
178 return factory.actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
179 case VLAN_PCP:
180 ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
181 return factory.actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
182 default:
183 log.warn("Unimplemented action type {}.", l2m.subtype());
184 break;
185 }
186 return null;
187 }
188
189 private Match buildMatch(List<Criterion> criteria, OFFactory factory) {
190 Match.Builder mBuilder = factory.buildMatch();
191 EthCriterion eth;
192 IPCriterion ip;
193 for (Criterion c : criteria) {
194 switch (c.type()) {
195 case IN_PORT:
196 PortCriterion inport = (PortCriterion) c;
197 mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
198 break;
199 case ETH_SRC:
200 eth = (EthCriterion) c;
201 mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
202 break;
203 case ETH_DST:
204 eth = (EthCriterion) c;
205 mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
206 break;
207 case ETH_TYPE:
208 EthTypeCriterion ethType = (EthTypeCriterion) c;
209 mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
210 case IPV4_DST:
211 ip = (IPCriterion) c;
alshabib64231f62014-09-16 17:58:36 -0700212 mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
alshabib35edb1a2014-09-16 17:44:44 -0700213 break;
214 case IPV4_SRC:
215 ip = (IPCriterion) c;
alshabib64231f62014-09-16 17:58:36 -0700216 mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
alshabib35edb1a2014-09-16 17:44:44 -0700217 break;
218 case IP_PROTO:
219 IPProtocolCriterion p = (IPProtocolCriterion) c;
220 mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
221 break;
222 case VLAN_PCP:
223 VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
224 mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
225 break;
226 case VLAN_VID:
227 VlanIdCriterion vid = (VlanIdCriterion) c;
228 mBuilder.setExact(MatchField.VLAN_VID,
229 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
230 break;
231 case ARP_OP:
232 case ARP_SHA:
233 case ARP_SPA:
234 case ARP_THA:
235 case ARP_TPA:
236 case ICMPV4_CODE:
237 case ICMPV4_TYPE:
238 case ICMPV6_CODE:
239 case ICMPV6_TYPE:
240 case IN_PHY_PORT:
241 case IPV6_DST:
242 case IPV6_EXTHDR:
243 case IPV6_FLABEL:
244 case IPV6_ND_SLL:
245 case IPV6_ND_TARGET:
246 case IPV6_ND_TLL:
247 case IPV6_SRC:
248 case IP_DSCP:
249 case IP_ECN:
250 case METADATA:
251 case MPLS_BOS:
252 case MPLS_LABEL:
253 case MPLS_TC:
254 case PBB_ISID:
255 case SCTP_DST:
256 case SCTP_SRC:
257 case TCP_DST:
258 case TCP_SRC:
259 case TUNNEL_ID:
260 case UDP_DST:
261 case UDP_SRC:
262 default:
263 log.warn("Action type {} not yet implemented.", c.type());
264 }
265 }
266 return mBuilder.build();
267 }
268
alshabib1cc04f72014-09-16 16:09:58 -0700269 @Override
270 public void removeFlowRule(FlowRule... flowRules) {
271 // TODO Auto-generated method stub
272
273 }
274
275 @Override
276 public Iterable<FlowEntry> getFlowMetrics(DeviceId deviceId) {
277 // TODO Auto-generated method stub
278 return null;
279 }
280
281
282 //TODO: InternalFlowRuleProvider listening to stats and error and flowremoved.
283 // possibly barriers as well. May not be internal at all...
284
285
286}