blob: 51fde29390ecf23151a1d3debc57c89d72cb8d1b [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;
tomc78acee2014-09-24 15:16:55 -070030import org.onlab.onos.net.flow.FlowRuleStoreDelegate;
31import org.onlab.onos.net.host.HostStoreDelegate;
alshabib57044ba2014-09-16 15:58:01 -070032import org.onlab.onos.net.provider.AbstractProviderRegistry;
33import org.onlab.onos.net.provider.AbstractProviderService;
34import org.slf4j.Logger;
35
alshabiba7f7ca82014-09-22 11:41:23 -070036import com.google.common.collect.Lists;
37
tome4729872014-09-23 00:37:37 -070038/**
39 * Provides implementation of the flow NB & SB APIs.
40 */
alshabib57044ba2014-09-16 15:58:01 -070041@Component(immediate = true)
42@Service
tom202175a2014-09-19 19:00:11 -070043public class FlowRuleManager
alshabiba7f7ca82014-09-22 11:41:23 -070044extends AbstractProviderRegistry<FlowRuleProvider, FlowRuleProviderService>
45implements FlowRuleService, FlowRuleProviderRegistry {
alshabib57044ba2014-09-16 15:58:01 -070046
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070047 public static final String FLOW_RULE_NULL = "FlowRule cannot be null";
alshabib57044ba2014-09-16 15:58:01 -070048 private final Logger log = getLogger(getClass());
49
50 private final AbstractListenerRegistry<FlowRuleEvent, FlowRuleListener>
alshabiba7f7ca82014-09-22 11:41:23 -070051 listenerRegistry = new AbstractListenerRegistry<>();
alshabib57044ba2014-09-16 15:58:01 -070052
tomc78acee2014-09-24 15:16:55 -070053 private FlowRuleStoreDelegate delegate = new InternalStoreDelegate();
54
tombe988312014-09-19 18:38:47 -070055 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected FlowRuleStore store;
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070057
alshabib57044ba2014-09-16 15:58:01 -070058 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070059 protected EventDeliveryService eventDispatcher;
alshabib57044ba2014-09-16 15:58:01 -070060
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070062 protected DeviceService deviceService;
alshabib57044ba2014-09-16 15:58:01 -070063
64 @Activate
65 public void activate() {
tomc78acee2014-09-24 15:16:55 -070066 store.setDelegate(delegate);
alshabib57044ba2014-09-16 15:58:01 -070067 eventDispatcher.addSink(FlowRuleEvent.class, listenerRegistry);
68 log.info("Started");
69 }
70
71 @Deactivate
72 public void deactivate() {
tomc78acee2014-09-24 15:16:55 -070073 store.unsetDelegate(delegate);
alshabib57044ba2014-09-16 15:58:01 -070074 eventDispatcher.removeSink(FlowRuleEvent.class);
75 log.info("Stopped");
76 }
77
78 @Override
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070079 public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -070080 return store.getFlowEntries(deviceId);
alshabib57044ba2014-09-16 15:58:01 -070081 }
82
83 @Override
alshabib219ebaa2014-09-22 15:41:24 -070084 public void applyFlowRules(FlowRule... flowRules) {
alshabib57044ba2014-09-16 15:58:01 -070085 for (int i = 0; i < flowRules.length; i++) {
alshabiba7f7ca82014-09-22 11:41:23 -070086 FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD);
alshabib57044ba2014-09-16 15:58:01 -070087 final Device device = deviceService.getDevice(f.deviceId());
88 final FlowRuleProvider frp = getProvider(device.providerId());
alshabib219ebaa2014-09-22 15:41:24 -070089 store.storeFlowRule(f);
alshabib57044ba2014-09-16 15:58:01 -070090 frp.applyFlowRule(f);
91 }
alshabib57044ba2014-09-16 15:58:01 -070092 }
93
94 @Override
95 public void removeFlowRules(FlowRule... flowRules) {
alshabibbb8b1282014-09-22 17:00:18 -070096 FlowRule f;
alshabib57044ba2014-09-16 15:58:01 -070097 for (int i = 0; i < flowRules.length; i++) {
alshabibbb8b1282014-09-22 17:00:18 -070098 f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE);
alshabib57044ba2014-09-16 15:58:01 -070099 final Device device = deviceService.getDevice(f.deviceId());
100 final FlowRuleProvider frp = getProvider(device.providerId());
alshabib219ebaa2014-09-22 15:41:24 -0700101 store.deleteFlowRule(f);
alshabib57044ba2014-09-16 15:58:01 -0700102 frp.removeFlowRule(f);
103 }
104
105 }
106
107 @Override
108 public void addListener(FlowRuleListener listener) {
109 listenerRegistry.addListener(listener);
110 }
111
112 @Override
113 public void removeListener(FlowRuleListener listener) {
114 listenerRegistry.removeListener(listener);
115 }
116
117 @Override
118 protected FlowRuleProviderService createProviderService(
119 FlowRuleProvider provider) {
120 return new InternalFlowRuleProviderService(provider);
121 }
122
123 private class InternalFlowRuleProviderService
alshabiba7f7ca82014-09-22 11:41:23 -0700124 extends AbstractProviderService<FlowRuleProvider>
125 implements FlowRuleProviderService {
alshabib57044ba2014-09-16 15:58:01 -0700126
127 protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
128 super(provider);
129 }
130
131 @Override
132 public void flowRemoved(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700133 checkNotNull(flowRule, FLOW_RULE_NULL);
134 checkValidity();
135 FlowRuleEvent event = store.removeFlowRule(flowRule);
alshabib57044ba2014-09-16 15:58:01 -0700136
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700137 if (event != null) {
138 log.debug("Flow {} removed", flowRule);
139 post(event);
140 }
alshabib57044ba2014-09-16 15:58:01 -0700141 }
142
143 @Override
144 public void flowMissing(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700145 checkNotNull(flowRule, FLOW_RULE_NULL);
146 checkValidity();
alshabib54ce5892014-09-23 17:50:51 -0700147 log.debug("Flow {} has not been installed.", flowRule);
alshabib57044ba2014-09-16 15:58:01 -0700148
149 }
150
151 @Override
alshabib219ebaa2014-09-22 15:41:24 -0700152 public void extraneousFlow(FlowRule flowRule) {
153 checkNotNull(flowRule, FLOW_RULE_NULL);
154 checkValidity();
alshabib54ce5892014-09-23 17:50:51 -0700155 log.debug("Flow {} is on switch but not in store.", flowRule);
alshabib219ebaa2014-09-22 15:41:24 -0700156 }
157
158 @Override
alshabib57044ba2014-09-16 15:58:01 -0700159 public void flowAdded(FlowRule flowRule) {
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700160 checkNotNull(flowRule, FLOW_RULE_NULL);
161 checkValidity();
alshabib57044ba2014-09-16 15:58:01 -0700162
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700163 FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule);
164 if (event == null) {
alshabib219ebaa2014-09-22 15:41:24 -0700165 log.debug("No flow store event generated.");
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700166 } else {
alshabib219ebaa2014-09-22 15:41:24 -0700167 log.debug("Flow {} {}", flowRule, event.type());
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700168 post(event);
169 }
alshabib219ebaa2014-09-22 15:41:24 -0700170
alshabib57044ba2014-09-16 15:58:01 -0700171 }
172
Ayaka Koshibe08eabaa2014-09-17 14:59:25 -0700173 // Posts the specified event to the local event dispatcher.
174 private void post(FlowRuleEvent event) {
175 if (event != null) {
176 eventDispatcher.post(event);
177 }
178 }
alshabib5c370ff2014-09-18 10:12:14 -0700179
180 @Override
alshabiba7f7ca82014-09-22 11:41:23 -0700181 public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) {
182 List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
alshabibbb8b1282014-09-22 17:00:18 -0700183
184 Iterator<FlowRule> switchRulesIterator = flowEntries.iterator();
alshabiba7f7ca82014-09-22 11:41:23 -0700185
186 while (switchRulesIterator.hasNext()) {
187 FlowRule rule = switchRulesIterator.next();
188 if (storedRules.remove(rule)) {
alshabib219ebaa2014-09-22 15:41:24 -0700189 // we both have the rule, let's update some info then.
alshabiba7f7ca82014-09-22 11:41:23 -0700190 flowAdded(rule);
191 } else {
alshabib219ebaa2014-09-22 15:41:24 -0700192 // the device has a rule the store does not have
193 extraneousFlow(rule);
alshabiba7f7ca82014-09-22 11:41:23 -0700194 }
195 }
196 for (FlowRule rule : storedRules) {
alshabib54ce5892014-09-23 17:50:51 -0700197
alshabiba7f7ca82014-09-22 11:41:23 -0700198 // there are rules in the store that aren't on the switch
199 flowMissing(rule);
alshabib54ce5892014-09-23 17:50:51 -0700200
alshabiba7f7ca82014-09-22 11:41:23 -0700201 }
alshabib5c370ff2014-09-18 10:12:14 -0700202 }
alshabib57044ba2014-09-16 15:58:01 -0700203 }
204
tomc78acee2014-09-24 15:16:55 -0700205 // Store delegate to re-post events emitted from the store.
206 private class InternalStoreDelegate implements FlowRuleStoreDelegate {
207 @Override
208 public void notify(FlowRuleEvent event) {
209 eventDispatcher.post(event);
210 }
211 }
alshabib57044ba2014-09-16 15:58:01 -0700212}