blob: c03f11923300bb03e7eb98c46e48044d167e14e5 [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
alshabibeec3a062014-09-17 18:01:26 -07005import java.util.Map;
6
alshabib1cc04f72014-09-16 16:09:58 -07007import org.apache.felix.scr.annotations.Activate;
8import org.apache.felix.scr.annotations.Component;
9import org.apache.felix.scr.annotations.Deactivate;
10import org.apache.felix.scr.annotations.Reference;
11import org.apache.felix.scr.annotations.ReferenceCardinality;
12import org.onlab.onos.net.DeviceId;
alshabib8f1cf4a2014-09-17 14:44:48 -070013import org.onlab.onos.net.flow.DefaultFlowRule;
alshabib1cc04f72014-09-16 16:09:58 -070014import org.onlab.onos.net.flow.FlowRule;
15import org.onlab.onos.net.flow.FlowRuleProvider;
16import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
17import org.onlab.onos.net.flow.FlowRuleProviderService;
18import org.onlab.onos.net.provider.AbstractProvider;
19import org.onlab.onos.net.provider.ProviderId;
20import org.onlab.onos.net.topology.TopologyService;
tom9c94c5b2014-09-17 13:14:42 -070021import org.onlab.onos.openflow.controller.Dpid;
22import org.onlab.onos.openflow.controller.OpenFlowController;
alshabibeec3a062014-09-17 18:01:26 -070023import org.onlab.onos.openflow.controller.OpenFlowEventListener;
tom9c94c5b2014-09-17 13:14:42 -070024import org.onlab.onos.openflow.controller.OpenFlowSwitch;
alshabibce4e5782014-09-17 14:56:42 -070025import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
alshabib8f1cf4a2014-09-17 14:44:48 -070026import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
alshabib5c370ff2014-09-18 10:12:14 -070027import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
28import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
alshabib8f1cf4a2014-09-17 14:44:48 -070029import org.projectfloodlight.openflow.protocol.OFMessage;
30import org.projectfloodlight.openflow.protocol.OFPortStatus;
alshabib5c370ff2014-09-18 10:12:14 -070031import org.projectfloodlight.openflow.protocol.OFStatsReply;
32import org.projectfloodlight.openflow.protocol.OFStatsType;
alshabib1cc04f72014-09-16 16:09:58 -070033import org.slf4j.Logger;
34
alshabib5c370ff2014-09-18 10:12:14 -070035import com.google.common.collect.Lists;
36import com.google.common.collect.Maps;
37rt org.slf4j.Logger;
38
alshabibeec3a062014-09-17 18:01:26 -070039import com.google.common.collect.Maps;
40
alshabib1cc04f72014-09-16 16:09:58 -070041/**
42 * Provider which uses an OpenFlow controller to detect network
43 * end-station hosts.
44 */
45@Component(immediate = true)
46public class OpenFlowRuleProvider extends AbstractProvider implements FlowRuleProvider {
47
48 private final Logger log = getLogger(getClass());
49
50 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 protected FlowRuleProviderRegistry providerRegistry;
52
53 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 protected OpenFlowController controller;
55
56 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 protected TopologyService topologyService;
58
59 private FlowRuleProviderService providerService;
60
alshabibeec3a062014-09-17 18:01:26 -070061 private final InternalFlowProvider listener = new InternalFlowProvider();
62
alshabib1cc04f72014-09-16 16:09:58 -070063 /**
64 * Creates an OpenFlow host provider.
65 */
66 public OpenFlowRuleProvider() {
67 super(new ProviderId("org.onlab.onos.provider.openflow"));
68 }
69
70 @Activate
71 public void activate() {
72 providerService = providerRegistry.register(this);
alshabibeec3a062014-09-17 18:01:26 -070073 controller.addListener(listener);
74 controller.addEventListener(listener);
alshabib1cc04f72014-09-16 16:09:58 -070075 log.info("Started");
76 }
77
78 @Deactivate
79 public void deactivate() {
80 providerRegistry.unregister(this);
81 providerService = null;
82
83 log.info("Stopped");
84 }
85 @Override
86 public void applyFlowRule(FlowRule... flowRules) {
alshabib35edb1a2014-09-16 17:44:44 -070087 for (int i = 0; i < flowRules.length; i++) {
88 applyRule(flowRules[i]);
89 }
alshabib1cc04f72014-09-16 16:09:58 -070090 }
91
alshabib35edb1a2014-09-16 17:44:44 -070092 private void applyRule(FlowRule flowRule) {
93 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
alshabib8f1cf4a2014-09-17 14:44:48 -070094 sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowMod());
alshabib35edb1a2014-09-16 17:44:44 -070095 }
96
alshabib35edb1a2014-09-16 17:44:44 -070097
alshabib35edb1a2014-09-16 17:44:44 -070098
alshabib1cc04f72014-09-16 16:09:58 -070099 @Override
100 public void removeFlowRule(FlowRule... flowRules) {
101 // TODO Auto-generated method stub
102
103 }
104
alshabib1cc04f72014-09-16 16:09:58 -0700105
106 //TODO: InternalFlowRuleProvider listening to stats and error and flowremoved.
107 // possibly barriers as well. May not be internal at all...
alshabib8f1cf4a2014-09-17 14:44:48 -0700108 private class InternalFlowProvider
109 implements OpenFlowSwitchListener, OpenFlowEventListener {
110
alshabibeec3a062014-09-17 18:01:26 -0700111 private final Map<Dpid, FlowStatsCollector> collectors = Maps.newHashMap();
alshabib8f1cf4a2014-09-17 14:44:48 -0700112
113 @Override
114 public void switchAdded(Dpid dpid) {
alshabibeec3a062014-09-17 18:01:26 -0700115 FlowStatsCollector fsc = new FlowStatsCollector(controller.getSwitch(dpid), 1);
116 fsc.start();
117 collectors.put(dpid, fsc);
alshabib8f1cf4a2014-09-17 14:44:48 -0700118 }
119
120 @Override
121 public void switchRemoved(Dpid dpid) {
alshabibeec3a062014-09-17 18:01:26 -0700122 collectors.remove(dpid).stop();
alshabib8f1cf4a2014-09-17 14:44:48 -0700123 }
124
125 @Override
126 public void portChanged(Dpid dpid, OFPortStatus status) {
127 //TODO: Decide whether to evict flows internal store.
128 }
129
130 @Override
131 public void handleMessage(Dpid dpid, OFMessage msg) {
132 switch (msg.getType()) {
133 case FLOW_REMOVED:
alshabibeec3a062014-09-17 18:01:26 -0700134 //TODO: make this better
alshabib8f1cf4a2014-09-17 14:44:48 -0700135 OFFlowRemoved removed = (OFFlowRemoved) msg;
136 FlowRule fr = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), null, null);
137 providerService.flowRemoved(fr);
138 break;
139 case STATS_REPLY:
alshabib5c370ff2014-09-18 10:12:14 -0700140 pushFlowMetrics((OFStatsReply) msg);
alshabibeec3a062014-09-17 18:01:26 -0700141 break;
alshabib8f1cf4a2014-09-17 14:44:48 -0700142 case BARRIER_REPLY:
143 case ERROR:
144 default:
145 log.warn("Unhandled message type: {}", msg.getType());
146 }
147
148 }
149
alshabib5c370ff2014-09-18 10:12:14 -0700150 private void pushFlowMetrics(OFStatsReply stats) {
151 if (stats.getStatsType() != OFStatsType.FLOW) {
152 return;
153 }
154 final OFFlowStatsReply replies = (OFFlowStatsReply) stats;
155 final List<FlowEntry> entries = Lists.newLinkedList();
156 for (OFFlowStatsEntry reply : replies.getEntries()) {
157
158 }
159
160
161 }
162
alshabib8f1cf4a2014-09-17 14:44:48 -0700163 }
alshabib1cc04f72014-09-16 16:09:58 -0700164
165
166}