resilient flows and application id
Change-Id: Ic9f192d4451ae962737ab2b45c644372535e7bdb
Showing
11 changed files
with
232 additions
and
52 deletions
... | @@ -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 | + } | ||
98 | 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 | + } | ||
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(); |
141 | - log.debug("Flow {} has not been installed.", flowRule); | 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: | ||
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 | - | 121 | + flowEntries.remove(did, rule); |
83 | - flowEntries.remove(did, rule); | 122 | + flowEntries.put(did, rule); |
84 | - flowEntries.put(did, rule); | 123 | + //} |
85 | - } | ||
86 | return new FlowRuleEvent(Type.RULE_UPDATED, rule); | 124 | return new FlowRuleEvent(Type.RULE_UPDATED, rule); |
87 | } | 125 | } |
88 | 126 | ||
... | @@ -91,16 +129,20 @@ public class SimpleFlowRuleStore implements FlowRuleStore { | ... | @@ -91,16 +129,20 @@ 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 | - } | ||
101 | } | 138 | } |
139 | + //} | ||
102 | } | 140 | } |
103 | 141 | ||
104 | 142 | ||
105 | 143 | ||
144 | + | ||
145 | + | ||
146 | + | ||
147 | + | ||
106 | } | 148 | } | ... | ... |
... | @@ -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(); | ... | ... |
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment