alshabib

resilient flows and application id

Change-Id: Ic9f192d4451ae962737ab2b45c644372535e7bdb
...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component; ...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +import org.onlab.onos.ApplicationId;
12 import org.onlab.onos.net.Host; 13 import org.onlab.onos.net.Host;
13 import org.onlab.onos.net.HostId; 14 import org.onlab.onos.net.HostId;
14 import org.onlab.onos.net.Path; 15 import org.onlab.onos.net.Path;
...@@ -53,14 +54,18 @@ public class ReactiveForwarding { ...@@ -53,14 +54,18 @@ public class ReactiveForwarding {
53 54
54 private ReactivePacketProcessor processor = new ReactivePacketProcessor(); 55 private ReactivePacketProcessor processor = new ReactivePacketProcessor();
55 56
57 + private ApplicationId appId;
58 +
56 @Activate 59 @Activate
57 public void activate() { 60 public void activate() {
61 + appId = ApplicationId.getAppId();
58 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1); 62 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 1);
59 - log.info("Started"); 63 + log.info("Started with Application ID {}", appId.id());
60 } 64 }
61 65
62 @Deactivate 66 @Deactivate
63 public void deactivate() { 67 public void deactivate() {
68 + flowRuleService.removeFlowRulesById(appId);
64 packetService.removeProcessor(processor); 69 packetService.removeProcessor(processor);
65 processor = null; 70 processor = null;
66 log.info("Stopped"); 71 log.info("Stopped");
...@@ -169,7 +174,7 @@ public class ReactiveForwarding { ...@@ -169,7 +174,7 @@ public class ReactiveForwarding {
169 treat.add(Instructions.createOutput(portNumber)); 174 treat.add(Instructions.createOutput(portNumber));
170 175
171 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), 176 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
172 - builder.build(), treat.build(), 0); 177 + builder.build(), treat.build(), 0, appId);
173 178
174 flowRuleService.applyFlowRules(f); 179 flowRuleService.applyFlowRules(f);
175 } 180 }
......
...@@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import java.util.Objects; 6 import java.util.Objects;
7 7
8 +import org.onlab.onos.ApplicationId;
8 import org.onlab.onos.net.DeviceId; 9 import org.onlab.onos.net.DeviceId;
9 import org.slf4j.Logger; 10 import org.slf4j.Logger;
10 11
...@@ -24,6 +25,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -24,6 +25,8 @@ public class DefaultFlowRule implements FlowRule {
24 25
25 private final FlowId id; 26 private final FlowId id;
26 27
28 + private final ApplicationId appId;
29 +
27 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 30 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
28 TrafficTreatment treatment, int priority, FlowRuleState state, 31 TrafficTreatment treatment, int priority, FlowRuleState state,
29 long life, long packets, long bytes, long flowId) { 32 long life, long packets, long bytes, long flowId) {
...@@ -32,7 +35,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -32,7 +35,7 @@ public class DefaultFlowRule implements FlowRule {
32 this.selector = selector; 35 this.selector = selector;
33 this.treatment = treatment; 36 this.treatment = treatment;
34 this.state = state; 37 this.state = state;
35 - 38 + this.appId = ApplicationId.valueOf((int) (flowId >> 32));
36 this.id = FlowId.valueOf(flowId); 39 this.id = FlowId.valueOf(flowId);
37 40
38 this.life = life; 41 this.life = life;
...@@ -42,18 +45,18 @@ public class DefaultFlowRule implements FlowRule { ...@@ -42,18 +45,18 @@ public class DefaultFlowRule implements FlowRule {
42 } 45 }
43 46
44 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 47 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
45 - TrafficTreatment treatement, int priority) { 48 + TrafficTreatment treatement, int priority, ApplicationId appId) {
46 - this(deviceId, selector, treatement, priority, FlowRuleState.CREATED); 49 + this(deviceId, selector, treatement, priority, FlowRuleState.CREATED, appId);
47 } 50 }
48 51
49 public DefaultFlowRule(FlowRule rule, FlowRuleState state) { 52 public DefaultFlowRule(FlowRule rule, FlowRuleState state) {
50 this(rule.deviceId(), rule.selector(), rule.treatment(), 53 this(rule.deviceId(), rule.selector(), rule.treatment(),
51 - rule.priority(), state, rule.id()); 54 + rule.priority(), state, rule.id(), rule.appId());
52 } 55 }
53 56
54 private DefaultFlowRule(DeviceId deviceId, 57 private DefaultFlowRule(DeviceId deviceId,
55 TrafficSelector selector, TrafficTreatment treatment, 58 TrafficSelector selector, TrafficTreatment treatment,
56 - int priority, FlowRuleState state) { 59 + int priority, FlowRuleState state, ApplicationId appId) {
57 this.deviceId = deviceId; 60 this.deviceId = deviceId;
58 this.priority = priority; 61 this.priority = priority;
59 this.selector = selector; 62 this.selector = selector;
...@@ -62,13 +65,15 @@ public class DefaultFlowRule implements FlowRule { ...@@ -62,13 +65,15 @@ public class DefaultFlowRule implements FlowRule {
62 this.life = 0; 65 this.life = 0;
63 this.packets = 0; 66 this.packets = 0;
64 this.bytes = 0; 67 this.bytes = 0;
65 - this.id = FlowId.valueOf(this.hashCode()); 68 + this.appId = appId;
69 +
70 + this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL));
66 this.created = System.currentTimeMillis(); 71 this.created = System.currentTimeMillis();
67 } 72 }
68 73
69 private DefaultFlowRule(DeviceId deviceId, 74 private DefaultFlowRule(DeviceId deviceId,
70 TrafficSelector selector, TrafficTreatment treatment, 75 TrafficSelector selector, TrafficTreatment treatment,
71 - int priority, FlowRuleState state, FlowId flowId) { 76 + int priority, FlowRuleState state, FlowId flowId, ApplicationId appId) {
72 this.deviceId = deviceId; 77 this.deviceId = deviceId;
73 this.priority = priority; 78 this.priority = priority;
74 this.selector = selector; 79 this.selector = selector;
...@@ -77,6 +82,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -77,6 +82,7 @@ public class DefaultFlowRule implements FlowRule {
77 this.life = 0; 82 this.life = 0;
78 this.packets = 0; 83 this.packets = 0;
79 this.bytes = 0; 84 this.bytes = 0;
85 + this.appId = appId;
80 this.id = flowId; 86 this.id = flowId;
81 this.created = System.currentTimeMillis(); 87 this.created = System.currentTimeMillis();
82 } 88 }
...@@ -88,6 +94,11 @@ public class DefaultFlowRule implements FlowRule { ...@@ -88,6 +94,11 @@ public class DefaultFlowRule implements FlowRule {
88 } 94 }
89 95
90 @Override 96 @Override
97 + public ApplicationId appId() {
98 + return appId;
99 + }
100 +
101 + @Override
91 public int priority() { 102 public int priority() {
92 return priority; 103 return priority;
93 } 104 }
...@@ -136,7 +147,11 @@ public class DefaultFlowRule implements FlowRule { ...@@ -136,7 +147,11 @@ public class DefaultFlowRule implements FlowRule {
136 * @see java.lang.Object#equals(java.lang.Object) 147 * @see java.lang.Object#equals(java.lang.Object)
137 */ 148 */
138 public int hashCode() { 149 public int hashCode() {
139 - return Objects.hash(deviceId, selector, treatment); 150 + return Objects.hash(deviceId, id);
151 + }
152 +
153 + public int hash() {
154 + return Objects.hash(deviceId, selector, id);
140 } 155 }
141 156
142 @Override 157 @Override
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
4 5
5 /** 6 /**
...@@ -53,6 +54,13 @@ public interface FlowRule { ...@@ -53,6 +54,13 @@ public interface FlowRule {
53 FlowId id(); 54 FlowId id();
54 55
55 /** 56 /**
57 + * Returns the application id of this flow.
58 + *
59 + * @return an applicationId
60 + */
61 + ApplicationId appId();
62 +
63 + /**
56 * Returns the flow rule priority given in natural order; higher numbers 64 * Returns the flow rule priority given in natural order; higher numbers
57 * mean higher priorities. 65 * mean higher priorities.
58 * 66 *
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.provider.Provider; 4 import org.onlab.onos.net.provider.Provider;
4 5
5 /** 6 /**
...@@ -25,4 +26,10 @@ public interface FlowRuleProvider extends Provider { ...@@ -25,4 +26,10 @@ public interface FlowRuleProvider extends Provider {
25 */ 26 */
26 void removeFlowRule(FlowRule... flowRules); 27 void removeFlowRule(FlowRule... flowRules);
27 28
29 + /**
30 + * Removes rules by their id.
31 + * @param id the id to remove
32 + */
33 + void removeRulesById(ApplicationId id, FlowRule... flowRules);
34 +
28 } 35 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
4 5
5 /** 6 /**
...@@ -43,6 +44,20 @@ public interface FlowRuleService { ...@@ -43,6 +44,20 @@ public interface FlowRuleService {
43 */ 44 */
44 void removeFlowRules(FlowRule... flowRules); 45 void removeFlowRules(FlowRule... flowRules);
45 46
47 + /**
48 + * Removes all rules by id.
49 + *
50 + * @param appId id to remove
51 + */
52 + void removeFlowRulesById(ApplicationId appId);
53 +
54 + /**
55 + * Returns a list of rules with this application id.
56 + *
57 + * @param id the id to look up
58 + * @return collection of flow rules
59 + */
60 + Iterable<FlowRule> getFlowRulesById(ApplicationId id);
46 61
47 /** 62 /**
48 * Adds the specified flow rule listener. 63 * Adds the specified flow rule listener.
...@@ -58,4 +73,6 @@ public interface FlowRuleService { ...@@ -58,4 +73,6 @@ public interface FlowRuleService {
58 */ 73 */
59 void removeListener(FlowRuleListener listener); 74 void removeListener(FlowRuleListener listener);
60 75
76 +
77 +
61 } 78 }
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 +import org.onlab.onos.ApplicationId;
3 import org.onlab.onos.net.DeviceId; 4 import org.onlab.onos.net.DeviceId;
4 5
5 /** 6 /**
...@@ -8,6 +9,13 @@ import org.onlab.onos.net.DeviceId; ...@@ -8,6 +9,13 @@ import org.onlab.onos.net.DeviceId;
8 public interface FlowRuleStore { 9 public interface FlowRuleStore {
9 10
10 /** 11 /**
12 + * Returns the stored flow.
13 + * @param rule the rule to look for
14 + * @return a flow rule
15 + */
16 + FlowRule getFlowRule(FlowRule rule);
17 +
18 + /**
11 * Returns the flow entries associated with a device. 19 * Returns the flow entries associated with a device.
12 * 20 *
13 * @param deviceId the device ID 21 * @param deviceId the device ID
...@@ -16,6 +24,14 @@ public interface FlowRuleStore { ...@@ -16,6 +24,14 @@ public interface FlowRuleStore {
16 Iterable<FlowRule> getFlowEntries(DeviceId deviceId); 24 Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
17 25
18 /** 26 /**
27 + * Returns the flow entries associated with an application.
28 + *
29 + * @param appId the application id
30 + * @return the flow entries
31 + */
32 + Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId);
33 +
34 + /**
19 * Stores a new flow rule without generating events. 35 * Stores a new flow rule without generating events.
20 * 36 *
21 * @param rule the flow rule to add 37 * @param rule the flow rule to add
......
...@@ -12,14 +12,13 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -12,14 +12,13 @@ import org.apache.felix.scr.annotations.Deactivate;
12 import org.apache.felix.scr.annotations.Reference; 12 import org.apache.felix.scr.annotations.Reference;
13 import org.apache.felix.scr.annotations.ReferenceCardinality; 13 import org.apache.felix.scr.annotations.ReferenceCardinality;
14 import org.apache.felix.scr.annotations.Service; 14 import org.apache.felix.scr.annotations.Service;
15 +import org.onlab.onos.ApplicationId;
15 import org.onlab.onos.event.AbstractListenerRegistry; 16 import org.onlab.onos.event.AbstractListenerRegistry;
16 import org.onlab.onos.event.EventDeliveryService; 17 import org.onlab.onos.event.EventDeliveryService;
17 import org.onlab.onos.net.Device; 18 import org.onlab.onos.net.Device;
18 import org.onlab.onos.net.DeviceId; 19 import org.onlab.onos.net.DeviceId;
19 import org.onlab.onos.net.device.DeviceService; 20 import org.onlab.onos.net.device.DeviceService;
20 -import org.onlab.onos.net.flow.DefaultFlowRule;
21 import org.onlab.onos.net.flow.FlowRule; 21 import org.onlab.onos.net.flow.FlowRule;
22 -import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
23 import org.onlab.onos.net.flow.FlowRuleEvent; 22 import org.onlab.onos.net.flow.FlowRuleEvent;
24 import org.onlab.onos.net.flow.FlowRuleListener; 23 import org.onlab.onos.net.flow.FlowRuleListener;
25 import org.onlab.onos.net.flow.FlowRuleProvider; 24 import org.onlab.onos.net.flow.FlowRuleProvider;
...@@ -77,7 +76,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -77,7 +76,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
77 @Override 76 @Override
78 public void applyFlowRules(FlowRule... flowRules) { 77 public void applyFlowRules(FlowRule... flowRules) {
79 for (int i = 0; i < flowRules.length; i++) { 78 for (int i = 0; i < flowRules.length; i++) {
80 - FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD); 79 + FlowRule f = flowRules[i];
81 final Device device = deviceService.getDevice(f.deviceId()); 80 final Device device = deviceService.getDevice(f.deviceId());
82 final FlowRuleProvider frp = getProvider(device.providerId()); 81 final FlowRuleProvider frp = getProvider(device.providerId());
83 store.storeFlowRule(f); 82 store.storeFlowRule(f);
...@@ -88,14 +87,33 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -88,14 +87,33 @@ implements FlowRuleService, FlowRuleProviderRegistry {
88 @Override 87 @Override
89 public void removeFlowRules(FlowRule... flowRules) { 88 public void removeFlowRules(FlowRule... flowRules) {
90 FlowRule f; 89 FlowRule f;
90 + FlowRuleProvider frp;
91 + Device device;
91 for (int i = 0; i < flowRules.length; i++) { 92 for (int i = 0; i < flowRules.length; i++) {
92 - f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE); 93 + f = flowRules[i];
93 - final Device device = deviceService.getDevice(f.deviceId()); 94 + device = deviceService.getDevice(f.deviceId());
94 - final FlowRuleProvider frp = getProvider(device.providerId()); 95 + frp = getProvider(device.providerId());
95 store.deleteFlowRule(f); 96 store.deleteFlowRule(f);
96 frp.removeFlowRule(f); 97 frp.removeFlowRule(f);
97 } 98 }
99 + }
100 +
101 + @Override
102 + public void removeFlowRulesById(ApplicationId id) {
103 + Iterable<FlowRule> rules = getFlowRulesById(id);
104 + FlowRuleProvider frp;
105 + Device device;
106 + for (FlowRule f : rules) {
107 + store.deleteFlowRule(f);
108 + device = deviceService.getDevice(f.deviceId());
109 + frp = getProvider(device.providerId());
110 + frp.removeRulesById(id, f);
111 + }
112 + }
98 113
114 + @Override
115 + public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
116 + return store.getFlowEntriesByAppId(id);
99 } 117 }
100 118
101 @Override 119 @Override
...@@ -126,8 +144,27 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -126,8 +144,27 @@ implements FlowRuleService, FlowRuleProviderRegistry {
126 public void flowRemoved(FlowRule flowRule) { 144 public void flowRemoved(FlowRule flowRule) {
127 checkNotNull(flowRule, FLOW_RULE_NULL); 145 checkNotNull(flowRule, FLOW_RULE_NULL);
128 checkValidity(); 146 checkValidity();
129 - FlowRuleEvent event = store.removeFlowRule(flowRule); 147 + FlowRule stored = store.getFlowRule(flowRule);
148 + if (stored == null) {
149 + log.debug("Rule already evicted from store: {}", flowRule);
150 + return;
151 + }
152 + Device device = deviceService.getDevice(flowRule.deviceId());
153 + FlowRuleProvider frp = getProvider(device.providerId());
154 + FlowRuleEvent event = null;
155 + switch (stored.state()) {
156 + case ADDED:
157 + case PENDING_ADD:
158 + frp.applyFlowRule(flowRule);
159 + break;
160 + case PENDING_REMOVE:
161 + case REMOVED:
162 + event = store.removeFlowRule(flowRule);
163 + break;
164 + default:
165 + break;
130 166
167 + }
131 if (event != null) { 168 if (event != null) {
132 log.debug("Flow {} removed", flowRule); 169 log.debug("Flow {} removed", flowRule);
133 post(event); 170 post(event);
...@@ -138,7 +175,22 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -138,7 +175,22 @@ implements FlowRuleService, FlowRuleProviderRegistry {
138 public void flowMissing(FlowRule flowRule) { 175 public void flowMissing(FlowRule flowRule) {
139 checkNotNull(flowRule, FLOW_RULE_NULL); 176 checkNotNull(flowRule, FLOW_RULE_NULL);
140 checkValidity(); 177 checkValidity();
178 + Device device = deviceService.getDevice(flowRule.deviceId());
179 + FlowRuleProvider frp = getProvider(device.providerId());
180 + switch (flowRule.state()) {
181 + case PENDING_REMOVE:
182 + case REMOVED:
183 + store.removeFlowRule(flowRule);
184 + frp.removeFlowRule(flowRule);
185 + break;
186 + case ADDED:
187 + case PENDING_ADD:
188 + frp.applyFlowRule(flowRule);
189 + break;
190 + default:
141 log.debug("Flow {} has not been installed.", flowRule); 191 log.debug("Flow {} has not been installed.", flowRule);
192 + }
193 +
142 194
143 } 195 }
144 196
...@@ -146,6 +198,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -146,6 +198,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
146 public void extraneousFlow(FlowRule flowRule) { 198 public void extraneousFlow(FlowRule flowRule) {
147 checkNotNull(flowRule, FLOW_RULE_NULL); 199 checkNotNull(flowRule, FLOW_RULE_NULL);
148 checkValidity(); 200 checkValidity();
201 + removeFlowRules(flowRule);
149 log.debug("Flow {} is on switch but not in store.", flowRule); 202 log.debug("Flow {} is on switch but not in store.", flowRule);
150 } 203 }
151 204
......
...@@ -14,6 +14,7 @@ import java.util.List; ...@@ -14,6 +14,7 @@ import java.util.List;
14 import org.junit.After; 14 import org.junit.After;
15 import org.junit.Before; 15 import org.junit.Before;
16 import org.junit.Test; 16 import org.junit.Test;
17 +import org.onlab.onos.ApplicationId;
17 import org.onlab.onos.event.impl.TestEventDispatcher; 18 import org.onlab.onos.event.impl.TestEventDispatcher;
18 import org.onlab.onos.net.DefaultDevice; 19 import org.onlab.onos.net.DefaultDevice;
19 import org.onlab.onos.net.Device; 20 import org.onlab.onos.net.Device;
...@@ -61,6 +62,7 @@ public class FlowRuleManagerTest { ...@@ -61,6 +62,7 @@ public class FlowRuleManagerTest {
61 protected FlowRuleProviderService providerService; 62 protected FlowRuleProviderService providerService;
62 protected TestProvider provider; 63 protected TestProvider provider;
63 protected TestListener listener = new TestListener(); 64 protected TestListener listener = new TestListener();
65 + private ApplicationId appId;
64 66
65 @Before 67 @Before
66 public void setUp() { 68 public void setUp() {
...@@ -75,6 +77,7 @@ public class FlowRuleManagerTest { ...@@ -75,6 +77,7 @@ public class FlowRuleManagerTest {
75 mgr.addListener(listener); 77 mgr.addListener(listener);
76 provider = new TestProvider(PID); 78 provider = new TestProvider(PID);
77 providerService = registry.register(provider); 79 providerService = registry.register(provider);
80 + appId = ApplicationId.getAppId();
78 assertTrue("provider should be registered", 81 assertTrue("provider should be registered",
79 registry.getProviders().contains(provider.id())); 82 registry.getProviders().contains(provider.id()));
80 } 83 }
...@@ -93,7 +96,7 @@ public class FlowRuleManagerTest { ...@@ -93,7 +96,7 @@ public class FlowRuleManagerTest {
93 private FlowRule flowRule(int tsval, int trval) { 96 private FlowRule flowRule(int tsval, int trval) {
94 TestSelector ts = new TestSelector(tsval); 97 TestSelector ts = new TestSelector(tsval);
95 TestTreatment tr = new TestTreatment(trval); 98 TestTreatment tr = new TestTreatment(trval);
96 - return new DefaultFlowRule(DID, ts, tr, 0); 99 + return new DefaultFlowRule(DID, ts, tr, 0, appId);
97 } 100 }
98 101
99 private FlowRule flowRule(FlowRule rule, FlowRuleState state) { 102 private FlowRule flowRule(FlowRule rule, FlowRuleState state) {
...@@ -159,8 +162,8 @@ public class FlowRuleManagerTest { ...@@ -159,8 +162,8 @@ public class FlowRuleManagerTest {
159 public void applyFlowRules() { 162 public void applyFlowRules() {
160 163
161 FlowRule r1 = flowRule(1, 1); 164 FlowRule r1 = flowRule(1, 1);
162 - FlowRule r2 = flowRule(1, 2); 165 + FlowRule r2 = flowRule(2, 2);
163 - FlowRule r3 = flowRule(1, 3); 166 + FlowRule r3 = flowRule(3, 3);
164 167
165 assertTrue("store should be empty", 168 assertTrue("store should be empty",
166 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty()); 169 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
...@@ -196,6 +199,7 @@ public class FlowRuleManagerTest { ...@@ -196,6 +199,7 @@ public class FlowRuleManagerTest {
196 @Test 199 @Test
197 public void flowRemoved() { 200 public void flowRemoved() {
198 FlowRule f1 = addFlowRule(1); 201 FlowRule f1 = addFlowRule(1);
202 + service.removeFlowRules(f1);
199 addFlowRule(2); 203 addFlowRule(2);
200 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED); 204 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
201 providerService.flowRemoved(rem1); 205 providerService.flowRemoved(rem1);
...@@ -293,6 +297,11 @@ public class FlowRuleManagerTest { ...@@ -293,6 +297,11 @@ public class FlowRuleManagerTest {
293 public void removeFlowRule(FlowRule... flowRules) { 297 public void removeFlowRule(FlowRule... flowRules) {
294 } 298 }
295 299
300 + @Override
301 + public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
302 + }
303 +
304 +
296 } 305 }
297 306
298 private class TestSelector implements TrafficSelector { 307 private class TestSelector implements TrafficSelector {
......
...@@ -4,12 +4,18 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED; ...@@ -4,12 +4,18 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
4 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; 4 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
5 import static org.slf4j.LoggerFactory.getLogger; 5 import static org.slf4j.LoggerFactory.getLogger;
6 6
7 +import java.util.Collection;
8 +import java.util.Collections;
9 +
7 import org.apache.felix.scr.annotations.Activate; 10 import org.apache.felix.scr.annotations.Activate;
8 import org.apache.felix.scr.annotations.Component; 11 import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 12 import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Service; 13 import org.apache.felix.scr.annotations.Service;
14 +import org.onlab.onos.ApplicationId;
11 import org.onlab.onos.net.DeviceId; 15 import org.onlab.onos.net.DeviceId;
16 +import org.onlab.onos.net.flow.DefaultFlowRule;
12 import org.onlab.onos.net.flow.FlowRule; 17 import org.onlab.onos.net.flow.FlowRule;
18 +import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
13 import org.onlab.onos.net.flow.FlowRuleEvent; 19 import org.onlab.onos.net.flow.FlowRuleEvent;
14 import org.onlab.onos.net.flow.FlowRuleEvent.Type; 20 import org.onlab.onos.net.flow.FlowRuleEvent.Type;
15 import org.onlab.onos.net.flow.FlowRuleStore; 21 import org.onlab.onos.net.flow.FlowRuleStore;
...@@ -29,7 +35,11 @@ public class SimpleFlowRuleStore implements FlowRuleStore { ...@@ -29,7 +35,11 @@ public class SimpleFlowRuleStore implements FlowRuleStore {
29 private final Logger log = getLogger(getClass()); 35 private final Logger log = getLogger(getClass());
30 36
31 // store entries as a pile of rules, no info about device tables 37 // store entries as a pile of rules, no info about device tables
32 - private final Multimap<DeviceId, FlowRule> flowEntries = ArrayListMultimap.create(); 38 + private final Multimap<DeviceId, FlowRule> flowEntries =
39 + ArrayListMultimap.<DeviceId, FlowRule>create();
40 +
41 + private final Multimap<ApplicationId, FlowRule> flowEntriesById =
42 + ArrayListMultimap.<ApplicationId, FlowRule>create();
33 43
34 @Activate 44 @Activate
35 public void activate() { 45 public void activate() {
...@@ -41,48 +51,76 @@ public class SimpleFlowRuleStore implements FlowRuleStore { ...@@ -41,48 +51,76 @@ public class SimpleFlowRuleStore implements FlowRuleStore {
41 log.info("Stopped"); 51 log.info("Stopped");
42 } 52 }
43 53
54 +
44 @Override 55 @Override
45 - public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) { 56 + public synchronized FlowRule getFlowRule(FlowRule rule) {
46 - return ImmutableSet.copyOf(flowEntries.get(deviceId)); 57 + for (FlowRule f : flowEntries.get(rule.deviceId())) {
58 + if (f.equals(rule)) {
59 + return f;
60 + }
61 + }
62 + return null;
47 } 63 }
48 64
49 @Override 65 @Override
50 - public void storeFlowRule(FlowRule rule) { 66 + public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
51 - DeviceId did = rule.deviceId(); 67 + Collection<FlowRule> rules = flowEntries.get(deviceId);
52 - flowEntries.put(did, rule); 68 + if (rules == null) {
69 + return Collections.emptyList();
70 + }
71 + return ImmutableSet.copyOf(rules);
53 } 72 }
54 73
55 @Override 74 @Override
56 - public void deleteFlowRule(FlowRule rule) { 75 + public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
57 - DeviceId did = rule.deviceId(); 76 + Collection<FlowRule> rules = flowEntriesById.get(appId);
77 + if (rules == null) {
78 + return Collections.emptyList();
79 + }
80 + return ImmutableSet.copyOf(rules);
81 + }
82 +
83 + @Override
84 + public synchronized void storeFlowRule(FlowRule rule) {
85 + FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
86 + DeviceId did = f.deviceId();
87 + if (!flowEntries.containsEntry(did, f)) {
88 + flowEntries.put(did, f);
89 + flowEntriesById.put(rule.appId(), f);
90 + }
91 + }
92 +
93 + @Override
94 + public synchronized void deleteFlowRule(FlowRule rule) {
95 + FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
96 + DeviceId did = f.deviceId();
58 97
59 /* 98 /*
60 * find the rule and mark it for deletion. 99 * find the rule and mark it for deletion.
61 * Ultimately a flow removed will come remove it. 100 * Ultimately a flow removed will come remove it.
62 */ 101 */
63 102
64 - if (flowEntries.containsEntry(did, rule)) { 103 + if (flowEntries.containsEntry(did, f)) {
65 - synchronized (flowEntries) { 104 + //synchronized (flowEntries) {
66 - 105 + flowEntries.remove(did, f);
67 - flowEntries.remove(did, rule); 106 + flowEntries.put(did, f);
68 - flowEntries.put(did, rule); 107 + flowEntriesById.remove(rule.appId(), rule);
69 - } 108 + //}
70 } 109 }
71 } 110 }
72 111
73 @Override 112 @Override
74 - public FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) { 113 + public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
75 DeviceId did = rule.deviceId(); 114 DeviceId did = rule.deviceId();
76 115
77 // check if this new rule is an update to an existing entry 116 // check if this new rule is an update to an existing entry
78 if (flowEntries.containsEntry(did, rule)) { 117 if (flowEntries.containsEntry(did, rule)) {
79 - synchronized (flowEntries) { 118 + //synchronized (flowEntries) {
80 // Multimaps support duplicates so we have to remove our rule 119 // Multimaps support duplicates so we have to remove our rule
81 // and replace it with the current version. 120 // and replace it with the current version.
82 -
83 flowEntries.remove(did, rule); 121 flowEntries.remove(did, rule);
84 flowEntries.put(did, rule); 122 flowEntries.put(did, rule);
85 - } 123 + //}
86 return new FlowRuleEvent(Type.RULE_UPDATED, rule); 124 return new FlowRuleEvent(Type.RULE_UPDATED, rule);
87 } 125 }
88 126
...@@ -91,15 +129,19 @@ public class SimpleFlowRuleStore implements FlowRuleStore { ...@@ -91,15 +129,19 @@ public class SimpleFlowRuleStore implements FlowRuleStore {
91 } 129 }
92 130
93 @Override 131 @Override
94 - public FlowRuleEvent removeFlowRule(FlowRule rule) { 132 + public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
95 - synchronized (this) { 133 + //synchronized (this) {
96 if (flowEntries.remove(rule.deviceId(), rule)) { 134 if (flowEntries.remove(rule.deviceId(), rule)) {
97 return new FlowRuleEvent(RULE_REMOVED, rule); 135 return new FlowRuleEvent(RULE_REMOVED, rule);
98 } else { 136 } else {
99 return null; 137 return null;
100 } 138 }
139 + //}
101 } 140 }
102 - } 141 +
142 +
143 +
144 +
103 145
104 146
105 147
......
...@@ -183,7 +183,7 @@ public class FlowRuleBuilder { ...@@ -183,7 +183,7 @@ public class FlowRuleBuilder {
183 break; 183 break;
184 case ETH_DST: 184 case ETH_DST:
185 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong()); 185 MacAddress dMac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
186 - builder.add(Criteria.matchEthSrc(dMac)); 186 + builder.add(Criteria.matchEthDst(dMac));
187 break; 187 break;
188 case ETH_TYPE: 188 case ETH_TYPE:
189 int ethType = match.get(MatchField.ETH_TYPE).getValue(); 189 int ethType = match.get(MatchField.ETH_TYPE).getValue();
......
...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component; ...@@ -9,6 +9,7 @@ import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
10 import org.apache.felix.scr.annotations.Reference; 10 import org.apache.felix.scr.annotations.Reference;
11 import org.apache.felix.scr.annotations.ReferenceCardinality; 11 import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +import org.onlab.onos.ApplicationId;
12 import org.onlab.onos.net.DeviceId; 13 import org.onlab.onos.net.DeviceId;
13 import org.onlab.onos.net.flow.FlowRule; 14 import org.onlab.onos.net.flow.FlowRule;
14 import org.onlab.onos.net.flow.FlowRuleProvider; 15 import org.onlab.onos.net.flow.FlowRuleProvider;
...@@ -102,12 +103,17 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -102,12 +103,17 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
102 103
103 } 104 }
104 105
105 -
106 private void removeRule(FlowRule flowRule) { 106 private void removeRule(FlowRule flowRule) {
107 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri())); 107 OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
108 sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowDel()); 108 sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowDel());
109 } 109 }
110 110
111 + @Override
112 + public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
113 + // TODO: optimize using the ApplicationId
114 + removeFlowRule(flowRules);
115 + }
116 +
111 117
112 //TODO: InternalFlowRuleProvider listening to stats and error and flowremoved. 118 //TODO: InternalFlowRuleProvider listening to stats and error and flowremoved.
113 // possibly barriers as well. May not be internal at all... 119 // possibly barriers as well. May not be internal at all...
...@@ -179,4 +185,6 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -179,4 +185,6 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
179 } 185 }
180 186
181 187
188 +
189 +
182 } 190 }
......