blob: 5bd6fed228f4971da4602d6501b734c0144b8698 [file] [log] [blame]
tombe988312014-09-19 18:38:47 -07001package org.onlab.onos.net.flow.impl;
alshabib57044ba2014-09-16 15:58:01 -07002
alshabib5c370ff2014-09-18 10:12:14 -07003import static com.google.common.base.Preconditions.checkNotNull;
alshabib57044ba2014-09-16 15:58:01 -07004import static org.slf4j.LoggerFactory.getLogger;
5
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -07006import java.util.ArrayList;
alshabiba7f7ca82014-09-22 11:41:23 -07007import java.util.Iterator;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -07008import java.util.List;
9
alshabib57044ba2014-09-16 15:58:01 -070010import org.apache.felix.scr.annotations.Activate;
11import org.apache.felix.scr.annotations.Component;
12import org.apache.felix.scr.annotations.Deactivate;
13import org.apache.felix.scr.annotations.Reference;
14import org.apache.felix.scr.annotations.ReferenceCardinality;
15import org.apache.felix.scr.annotations.Service;
16import org.onlab.onos.event.AbstractListenerRegistry;
17import org.onlab.onos.event.EventDeliveryService;
18import org.onlab.onos.net.Device;
19import org.onlab.onos.net.DeviceId;
20import org.onlab.onos.net.device.DeviceService;
alshabiba7f7ca82014-09-22 11:41:23 -070021import org.onlab.onos.net.flow.DefaultFlowRule;
alshabib57044ba2014-09-16 15:58:01 -070022import org.onlab.onos.net.flow.FlowRule;
alshabiba7f7ca82014-09-22 11:41:23 -070023import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
alshabib57044ba2014-09-16 15:58:01 -070024import org.onlab.onos.net.flow.FlowRuleEvent;
25import org.onlab.onos.net.flow.FlowRuleListener;
26import org.onlab.onos.net.flow.FlowRuleProvider;
27import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
28import org.onlab.onos.net.flow.FlowRuleProviderService;
29import org.onlab.onos.net.flow.FlowRuleService;
tombe988312014-09-19 18:38:47 -070030import org.onlab.onos.net.flow.FlowRuleStore;
alshabib57044ba2014-09-16 15:58:01 -070031import org.onlab.onos.net.provider.AbstractProviderRegistry;
32import org.onlab.onos.net.provider.AbstractProviderService;
33import org.slf4j.Logger;
34
alshabiba7f7ca82014-09-22 11:41:23 -070035import com.google.common.collect.Lists;
36
alshabib57044ba2014-09-16 15:58:01 -070037@Component(immediate = true)
38@Service
tom202175a2014-09-19 19:00:11 -070039public class FlowRuleManager
alshabiba7f7ca82014-09-22 11:41:23 -070040extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
41implements FlowRuleService, FlowRuleProviderRegistry {
alshabib57044ba2014-09-16 15:58:01 -070042
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070043 public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
alshabib57044ba2014-09-16 15:58:01 -070044 private final Logger log = getLogger(getClass());
45
46 private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener>
alshabiba7f7ca82014-09-22 11:41:23 -070047 listenerRegistry = new AbstractListenerRegistry<>();
alshabib57044ba2014-09-16 15:58:01 -070048
tombe988312014-09-19 18:38:47 -070049 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
50 protected FlowRuleStore store;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070051
alshabib57044ba2014-09-16 15:58:01 -070052 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070053 protected EventDeliveryService eventDispatcher;
alshabib57044ba2014-09-16 15:58:01 -070054
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070056 protected DeviceService deviceService;
alshabib57044ba2014-09-16 15:58:01 -070057
58 @Activate
59 public void activate() {
60 eventDispatcher.addSink(FlowRuleEvent.class, listenerRegistry);
61 log.info("Started");
62 }
63
64 @Deactivate
65 public void deactivate() {
66 eventDispatcher.removeSink(FlowRuleEvent.class);
67 log.info("Stopped");
68 }
69
70 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070071 public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070072 return store.getFlowEntries(deviceId);
alshabib57044ba2014-09-16 15:58:01 -070073 }
74
75 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070076 public List<FlowRule> applyFlowRules(FlowRule... flowRules) {
77 List<FlowRule> entries = new ArrayList<FlowRule>();
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070078
alshabib57044ba2014-09-16 15:58:01 -070079 for (int i = 0; i < flowRules.length; i++) {
alshabiba7f7ca82014-09-22 11:41:23 -070080 FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD);
alshabib57044ba2014-09-16 15:58:01 -070081 final Device device = deviceService.getDevice(f.deviceId());
82 final FlowRuleProvider frp = getProvider(device.providerId());
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070083 entries.add(store.storeFlowRule(f));
alshabib57044ba2014-09-16 15:58:01 -070084 frp.applyFlowRule(f);
85 }
86
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070087 return entries;
alshabib57044ba2014-09-16 15:58:01 -070088 }
89
90 @Override
91 public void removeFlowRules(FlowRule... flowRules) {
92 for (int i = 0; i < flowRules.length; i++) {
alshabiba7f7ca82014-09-22 11:41:23 -070093 FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE);
alshabib57044ba2014-09-16 15:58:01 -070094 final Device device = deviceService.getDevice(f.deviceId());
95 final FlowRuleProvider frp = getProvider(device.providerId());
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070096 store.removeFlowRule(f);
alshabib57044ba2014-09-16 15:58:01 -070097 frp.removeFlowRule(f);
98 }
99
100 }
101
102 @Override
103 public void addListener(FlowRuleListener listener) {
104 listenerRegistry.addListener(listener);
105 }
106
107 @Override
108 public void removeListener(FlowRuleListener listener) {
109 listenerRegistry.removeListener(listener);
110 }
111
112 @Override
113 protected FlowRuleProviderService createProviderService(
114 FlowRuleProvider provider) {
115 return new InternalFlowRuleProviderService(provider);
116 }
117
118 private class InternalFlowRuleProviderService
alshabiba7f7ca82014-09-22 11:41:23 -0700119 extends AbstractProviderService<FlowRuleProvider>
120 implements FlowRuleProviderService {
alshabib57044ba2014-09-16 15:58:01 -0700121
122 protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
123 super(provider);
124 }
125
126 @Override
127 public void flowRemoved(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700128 checkNotNull(flowRule, FLOW_RULE_NULL);
129 checkValidity();
130 FlowRuleEvent event = store.removeFlowRule(flowRule);
alshabib57044ba2014-09-16 15:58:01 -0700131
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700132 if (event != null) {
133 log.debug("Flow {} removed", flowRule);
134 post(event);
135 }
alshabib57044ba2014-09-16 15:58:01 -0700136 }
137
138 @Override
139 public void flowMissing(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700140 checkNotNull(flowRule, FLOW_RULE_NULL);
141 checkValidity();
alshabib57044ba2014-09-16 15:58:01 -0700142 // TODO Auto-generated method stub
143
144 }
145
146 @Override
147 public void flowAdded(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700148 checkNotNull(flowRule, FLOW_RULE_NULL);
149 checkValidity();
alshabib57044ba2014-09-16 15:58:01 -0700150
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700151 FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule);
152 if (event == null) {
153 log.debug("Flow {} updated", flowRule);
154 } else {
155 log.debug("Flow {} added", flowRule);
156 post(event);
157 }
alshabib57044ba2014-09-16 15:58:01 -0700158 }
159
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700160 // Posts the specified event to the local event dispatcher.
161 private void post(FlowRuleEvent event) {
162 if (event != null) {
163 eventDispatcher.post(event);
164 }
165 }
alshabib5c370ff2014-09-18 10:12:14 -0700166
167 @Override
alshabiba7f7ca82014-09-22 11:41:23 -0700168 public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) {
169 List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
170 List<FlowRule> switchRules = Lists.newLinkedList(flowEntries);
171 Iterator<FlowRule> switchRulesIterator = switchRules.iterator();
172 List<FlowRule> extraRules = Lists.newLinkedList();
173
174 while (switchRulesIterator.hasNext()) {
175 FlowRule rule = switchRulesIterator.next();
176 if (storedRules.remove(rule)) {
177 // we both have the rule let's update some info then.
178 log.info("rule {} is added. {}", rule.id(), rule.state());
179 flowAdded(rule);
180 } else {
181 // the device a rule the store does not have
182 extraRules.add(rule);
183 }
184 }
185 for (FlowRule rule : storedRules) {
186 // there are rules in the store that aren't on the switch
187 flowMissing(rule);
188 }
189 if (extraRules.size() > 0) {
190 log.warn("Device {} has extra flow rules: {}", deviceId, extraRules);
191 // TODO do something with this.
192 }
193
alshabib5c370ff2014-09-18 10:12:14 -0700194
195 }
alshabib57044ba2014-09-16 15:58:01 -0700196 }
197
198}