blob: 51ea3280941fdd6a8131d574623e06c64e0be2df [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
alshabiba7f7ca82014-09-22 11:41:23 -07006import java.util.Iterator;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -07007import java.util.List;
8
alshabib57044ba2014-09-16 15:58:01 -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.apache.felix.scr.annotations.Service;
15import org.onlab.onos.event.AbstractListenerRegistry;
16import org.onlab.onos.event.EventDeliveryService;
17import org.onlab.onos.net.Device;
18import org.onlab.onos.net.DeviceId;
19import org.onlab.onos.net.device.DeviceService;
alshabiba7f7ca82014-09-22 11:41:23 -070020import org.onlab.onos.net.flow.DefaultFlowRule;
alshabib57044ba2014-09-16 15:58:01 -070021import org.onlab.onos.net.flow.FlowRule;
alshabiba7f7ca82014-09-22 11:41:23 -070022import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
alshabib57044ba2014-09-16 15:58:01 -070023import org.onlab.onos.net.flow.FlowRuleEvent;
24import org.onlab.onos.net.flow.FlowRuleListener;
25import org.onlab.onos.net.flow.FlowRuleProvider;
26import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
27import org.onlab.onos.net.flow.FlowRuleProviderService;
28import org.onlab.onos.net.flow.FlowRuleService;
tombe988312014-09-19 18:38:47 -070029import org.onlab.onos.net.flow.FlowRuleStore;
alshabib57044ba2014-09-16 15:58:01 -070030import org.onlab.onos.net.provider.AbstractProviderRegistry;
31import org.onlab.onos.net.provider.AbstractProviderService;
32import org.slf4j.Logger;
33
alshabiba7f7ca82014-09-22 11:41:23 -070034import com.google.common.collect.Lists;
35
alshabib57044ba2014-09-16 15:58:01 -070036@Component(immediate = true)
37@Service
tom202175a2014-09-19 19:00:11 -070038public class FlowRuleManager
alshabiba7f7ca82014-09-22 11:41:23 -070039extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
40implements FlowRuleService, FlowRuleProviderRegistry {
alshabib57044ba2014-09-16 15:58:01 -070041
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070042 public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
alshabib57044ba2014-09-16 15:58:01 -070043 private final Logger log = getLogger(getClass());
44
45 private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener>
alshabiba7f7ca82014-09-22 11:41:23 -070046 listenerRegistry = new AbstractListenerRegistry<>();
alshabib57044ba2014-09-16 15:58:01 -070047
tombe988312014-09-19 18:38:47 -070048 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
49 protected FlowRuleStore store;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070050
alshabib57044ba2014-09-16 15:58:01 -070051 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070052 protected EventDeliveryService eventDispatcher;
alshabib57044ba2014-09-16 15:58:01 -070053
54 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070055 protected DeviceService deviceService;
alshabib57044ba2014-09-16 15:58:01 -070056
57 @Activate
58 public void activate() {
59 eventDispatcher.addSink(FlowRuleEvent.class, listenerRegistry);
60 log.info("Started");
61 }
62
63 @Deactivate
64 public void deactivate() {
65 eventDispatcher.removeSink(FlowRuleEvent.class);
66 log.info("Stopped");
67 }
68
69 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070070 public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070071 return store.getFlowEntries(deviceId);
alshabib57044ba2014-09-16 15:58:01 -070072 }
73
74 @Override
alshabib219ebaa2014-09-22 15:41:24 -070075 public void applyFlowRules(FlowRule... flowRules) {
alshabib57044ba2014-09-16 15:58:01 -070076 for (int i = 0; i < flowRules.length; i++) {
alshabiba7f7ca82014-09-22 11:41:23 -070077 FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD);
alshabib57044ba2014-09-16 15:58:01 -070078 final Device device = deviceService.getDevice(f.deviceId());
79 final FlowRuleProvider frp = getProvider(device.providerId());
alshabib219ebaa2014-09-22 15:41:24 -070080 store.storeFlowRule(f);
alshabib57044ba2014-09-16 15:58:01 -070081 frp.applyFlowRule(f);
82 }
alshabib57044ba2014-09-16 15:58:01 -070083 }
84
85 @Override
86 public void removeFlowRules(FlowRule... flowRules) {
alshabibbb8b1282014-09-22 17:00:18 -070087 FlowRule f;
alshabib57044ba2014-09-16 15:58:01 -070088 for (int i = 0; i < flowRules.length; i++) {
alshabibbb8b1282014-09-22 17:00:18 -070089 f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE);
alshabib57044ba2014-09-16 15:58:01 -070090 final Device device = deviceService.getDevice(f.deviceId());
91 final FlowRuleProvider frp = getProvider(device.providerId());
alshabib219ebaa2014-09-22 15:41:24 -070092 store.deleteFlowRule(f);
alshabib57044ba2014-09-16 15:58:01 -070093 frp.removeFlowRule(f);
94 }
95
96 }
97
98 @Override
99 public void addListener(FlowRuleListener listener) {
100 listenerRegistry.addListener(listener);
101 }
102
103 @Override
104 public void removeListener(FlowRuleListener listener) {
105 listenerRegistry.removeListener(listener);
106 }
107
108 @Override
109 protected FlowRuleProviderService createProviderService(
110 FlowRuleProvider provider) {
111 return new InternalFlowRuleProviderService(provider);
112 }
113
114 private class InternalFlowRuleProviderService
alshabiba7f7ca82014-09-22 11:41:23 -0700115 extends AbstractProviderService<FlowRuleProvider>
116 implements FlowRuleProviderService {
alshabib57044ba2014-09-16 15:58:01 -0700117
118 protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
119 super(provider);
120 }
121
122 @Override
123 public void flowRemoved(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700124 checkNotNull(flowRule, FLOW_RULE_NULL);
125 checkValidity();
126 FlowRuleEvent event = store.removeFlowRule(flowRule);
alshabib57044ba2014-09-16 15:58:01 -0700127
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700128 if (event != null) {
129 log.debug("Flow {} removed", flowRule);
130 post(event);
131 }
alshabib57044ba2014-09-16 15:58:01 -0700132 }
133
134 @Override
135 public void flowMissing(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700136 checkNotNull(flowRule, FLOW_RULE_NULL);
137 checkValidity();
alshabibbb8b1282014-09-22 17:00:18 -0700138 log.info("Flow {} has not been installed.", flowRule);
alshabib57044ba2014-09-16 15:58:01 -0700139
140 }
141
142 @Override
alshabib219ebaa2014-09-22 15:41:24 -0700143 public void extraneousFlow(FlowRule flowRule) {
144 checkNotNull(flowRule, FLOW_RULE_NULL);
145 checkValidity();
alshabibbb8b1282014-09-22 17:00:18 -0700146 log.info("Flow {} is on switch but not in store.", flowRule);
alshabib219ebaa2014-09-22 15:41:24 -0700147 }
148
149 @Override
alshabib57044ba2014-09-16 15:58:01 -0700150 public void flowAdded(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700151 checkNotNull(flowRule, FLOW_RULE_NULL);
152 checkValidity();
alshabib57044ba2014-09-16 15:58:01 -0700153
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700154 FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule);
155 if (event == null) {
alshabib219ebaa2014-09-22 15:41:24 -0700156 log.debug("No flow store event generated.");
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700157 } else {
alshabib219ebaa2014-09-22 15:41:24 -0700158 log.debug("Flow {} {}", flowRule, event.type());
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700159 post(event);
160 }
alshabib219ebaa2014-09-22 15:41:24 -0700161
alshabib57044ba2014-09-16 15:58:01 -0700162 }
163
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700164 // Posts the specified event to the local event dispatcher.
165 private void post(FlowRuleEvent event) {
166 if (event != null) {
167 eventDispatcher.post(event);
168 }
169 }
alshabib5c370ff2014-09-18 10:12:14 -0700170
171 @Override
alshabiba7f7ca82014-09-22 11:41:23 -0700172 public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) {
173 List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
alshabibbb8b1282014-09-22 17:00:18 -0700174
175 Iterator<FlowRule> switchRulesIterator = flowEntries.iterator();
alshabiba7f7ca82014-09-22 11:41:23 -0700176
177 while (switchRulesIterator.hasNext()) {
178 FlowRule rule = switchRulesIterator.next();
179 if (storedRules.remove(rule)) {
alshabib219ebaa2014-09-22 15:41:24 -0700180 // we both have the rule, let's update some info then.
alshabiba7f7ca82014-09-22 11:41:23 -0700181 flowAdded(rule);
182 } else {
alshabib219ebaa2014-09-22 15:41:24 -0700183 // the device has a rule the store does not have
184 extraneousFlow(rule);
alshabiba7f7ca82014-09-22 11:41:23 -0700185 }
186 }
187 for (FlowRule rule : storedRules) {
188 // there are rules in the store that aren't on the switch
189 flowMissing(rule);
190 }
alshabib5c370ff2014-09-18 10:12:14 -0700191 }
alshabib57044ba2014-09-16 15:58:01 -0700192 }
193
194}