flowrule states functional
Change-Id: Id310f146d4ef2a59993f31d60062464a24df4560
Showing
11 changed files
with
163 additions
and
81 deletions
1 | package org.onlab.onos.net.flow; | 1 | package org.onlab.onos.net.flow; |
2 | 2 | ||
3 | import static com.google.common.base.MoreObjects.toStringHelper; | 3 | import static com.google.common.base.MoreObjects.toStringHelper; |
4 | +import static org.slf4j.LoggerFactory.getLogger; | ||
4 | 5 | ||
5 | import java.util.Objects; | 6 | import java.util.Objects; |
6 | 7 | ||
7 | import org.onlab.onos.net.DeviceId; | 8 | import org.onlab.onos.net.DeviceId; |
9 | +import org.slf4j.Logger; | ||
8 | 10 | ||
9 | public class DefaultFlowRule implements FlowRule { | 11 | public class DefaultFlowRule implements FlowRule { |
10 | 12 | ||
13 | + private final Logger log = getLogger(getClass()); | ||
14 | + | ||
11 | private final DeviceId deviceId; | 15 | private final DeviceId deviceId; |
12 | private final int priority; | 16 | private final int priority; |
13 | private final TrafficSelector selector; | 17 | private final TrafficSelector selector; |
14 | private final TrafficTreatment treatment; | 18 | private final TrafficTreatment treatment; |
15 | - private final FlowId id; | ||
16 | private final long created; | 19 | private final long created; |
17 | private final long life; | 20 | private final long life; |
18 | private final long packets; | 21 | private final long packets; |
19 | private final long bytes; | 22 | private final long bytes; |
20 | private final FlowRuleState state; | 23 | private final FlowRuleState state; |
21 | 24 | ||
22 | - | 25 | + private final FlowId id; |
23 | - public DefaultFlowRule(DeviceId deviceId, | ||
24 | - TrafficSelector selector, TrafficTreatment treatment, | ||
25 | - int priority, FlowRuleState state) { | ||
26 | - this.deviceId = deviceId; | ||
27 | - this.priority = priority; | ||
28 | - this.selector = selector; | ||
29 | - this.treatment = treatment; | ||
30 | - this.state = state; | ||
31 | - this.life = 0; | ||
32 | - this.packets = 0; | ||
33 | - this.bytes = 0; | ||
34 | - this.id = FlowId.valueOf(this.hashCode()); | ||
35 | - this.created = System.currentTimeMillis(); | ||
36 | - } | ||
37 | 26 | ||
38 | public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, | 27 | public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, |
39 | TrafficTreatment treatment, int priority, FlowRuleState state, | 28 | TrafficTreatment treatment, int priority, FlowRuleState state, |
... | @@ -59,7 +48,37 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -59,7 +48,37 @@ public class DefaultFlowRule implements FlowRule { |
59 | 48 | ||
60 | public DefaultFlowRule(FlowRule rule, FlowRuleState state) { | 49 | public DefaultFlowRule(FlowRule rule, FlowRuleState state) { |
61 | this(rule.deviceId(), rule.selector(), rule.treatment(), | 50 | this(rule.deviceId(), rule.selector(), rule.treatment(), |
62 | - rule.priority(), state); | 51 | + rule.priority(), state, rule.id()); |
52 | + } | ||
53 | + | ||
54 | + private DefaultFlowRule(DeviceId deviceId, | ||
55 | + TrafficSelector selector, TrafficTreatment treatment, | ||
56 | + int priority, FlowRuleState state) { | ||
57 | + this.deviceId = deviceId; | ||
58 | + this.priority = priority; | ||
59 | + this.selector = selector; | ||
60 | + this.treatment = treatment; | ||
61 | + this.state = state; | ||
62 | + this.life = 0; | ||
63 | + this.packets = 0; | ||
64 | + this.bytes = 0; | ||
65 | + this.id = FlowId.valueOf(this.hashCode()); | ||
66 | + this.created = System.currentTimeMillis(); | ||
67 | + } | ||
68 | + | ||
69 | + private DefaultFlowRule(DeviceId deviceId, | ||
70 | + TrafficSelector selector, TrafficTreatment treatment, | ||
71 | + int priority, FlowRuleState state, FlowId flowId) { | ||
72 | + this.deviceId = deviceId; | ||
73 | + this.priority = priority; | ||
74 | + this.selector = selector; | ||
75 | + this.treatment = treatment; | ||
76 | + this.state = state; | ||
77 | + this.life = 0; | ||
78 | + this.packets = 0; | ||
79 | + this.bytes = 0; | ||
80 | + this.id = flowId; | ||
81 | + this.created = System.currentTimeMillis(); | ||
63 | } | 82 | } |
64 | 83 | ||
65 | 84 | ||
... | @@ -128,13 +147,14 @@ public class DefaultFlowRule implements FlowRule { | ... | @@ -128,13 +147,14 @@ public class DefaultFlowRule implements FlowRule { |
128 | * @see java.lang.Object#equals(java.lang.Object) | 147 | * @see java.lang.Object#equals(java.lang.Object) |
129 | */ | 148 | */ |
130 | public boolean equals(Object obj) { | 149 | public boolean equals(Object obj) { |
150 | + | ||
131 | if (this == obj) { | 151 | if (this == obj) { |
132 | return true; | 152 | return true; |
133 | } | 153 | } |
134 | if (obj instanceof FlowRule) { | 154 | if (obj instanceof FlowRule) { |
135 | - FlowRule that = (FlowRule) obj; | 155 | + DefaultFlowRule that = (DefaultFlowRule) obj; |
136 | - return Objects.equals(deviceId, that.deviceId()) && | 156 | + return Objects.equals(deviceId, that.deviceId) && |
137 | - Objects.equals(id, that.id()); | 157 | + Objects.equals(id, that.id); |
138 | } | 158 | } |
139 | return false; | 159 | return false; |
140 | } | 160 | } | ... | ... |
... | @@ -19,7 +19,12 @@ public class FlowRuleEvent extends AbstractEvent<FlowRuleEvent.Type, FlowRule> { | ... | @@ -19,7 +19,12 @@ public class FlowRuleEvent extends AbstractEvent<FlowRuleEvent.Type, FlowRule> { |
19 | /** | 19 | /** |
20 | * Signifies that a flow rule has been removed. | 20 | * Signifies that a flow rule has been removed. |
21 | */ | 21 | */ |
22 | - RULE_REMOVED | 22 | + RULE_REMOVED, |
23 | + | ||
24 | + /** | ||
25 | + * Signifies that a rule has been updated. | ||
26 | + */ | ||
27 | + RULE_UPDATED | ||
23 | } | 28 | } |
24 | 29 | ||
25 | /** | 30 | /** | ... | ... |
... | @@ -24,6 +24,13 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide | ... | @@ -24,6 +24,13 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide |
24 | void flowMissing(FlowRule flowRule); | 24 | void flowMissing(FlowRule flowRule); |
25 | 25 | ||
26 | /** | 26 | /** |
27 | + * Signals that a flow rule is on the switch but not in the store. | ||
28 | + * | ||
29 | + * @param flowRule the extra flow rule | ||
30 | + */ | ||
31 | + void extraneousFlow(FlowRule flowRule); | ||
32 | + | ||
33 | + /** | ||
27 | * Signals that a flow rule was indeed added. | 34 | * Signals that a flow rule was indeed added. |
28 | * | 35 | * |
29 | * @param flowRule the added flow rule | 36 | * @param flowRule the added flow rule |
... | @@ -38,4 +45,6 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide | ... | @@ -38,4 +45,6 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide |
38 | */ | 45 | */ |
39 | void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowRules); | 46 | void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowRules); |
40 | 47 | ||
48 | + | ||
49 | + | ||
41 | } | 50 | } | ... | ... |
1 | package org.onlab.onos.net.flow; | 1 | package org.onlab.onos.net.flow; |
2 | 2 | ||
3 | -import java.util.List; | ||
4 | - | ||
5 | import org.onlab.onos.net.DeviceId; | 3 | import org.onlab.onos.net.DeviceId; |
6 | 4 | ||
7 | /** | 5 | /** |
... | @@ -31,10 +29,8 @@ public interface FlowRuleService { | ... | @@ -31,10 +29,8 @@ public interface FlowRuleService { |
31 | * device reconnects to the controller. | 29 | * device reconnects to the controller. |
32 | * | 30 | * |
33 | * @param flowRules one or more flow rules | 31 | * @param flowRules one or more flow rules |
34 | - * throws SomeKindOfException that indicates which ones were applied and | ||
35 | - * which ones failed | ||
36 | */ | 32 | */ |
37 | - List<FlowRule> applyFlowRules(FlowRule... flowRules); | 33 | + void applyFlowRules(FlowRule... flowRules); |
38 | 34 | ||
39 | /** | 35 | /** |
40 | * Removes the specified flow rules from their respective devices. If the | 36 | * Removes the specified flow rules from their respective devices. If the | ... | ... |
... | @@ -16,12 +16,18 @@ public interface FlowRuleStore { | ... | @@ -16,12 +16,18 @@ public interface FlowRuleStore { |
16 | Iterable<FlowRule> getFlowEntries(DeviceId deviceId); | 16 | Iterable<FlowRule> getFlowEntries(DeviceId deviceId); |
17 | 17 | ||
18 | /** | 18 | /** |
19 | - * Stores a new flow rule, and generates a FlowRule for it. | 19 | + * Stores a new flow rule without generating events. |
20 | * | 20 | * |
21 | * @param rule the flow rule to add | 21 | * @param rule the flow rule to add |
22 | - * @return a flow entry | ||
23 | */ | 22 | */ |
24 | - FlowRule storeFlowRule(FlowRule rule); | 23 | + void storeFlowRule(FlowRule rule); |
24 | + | ||
25 | + /** | ||
26 | + * Deletes a flow rule without generating events. | ||
27 | + * | ||
28 | + * @param rule the flow rule to delete | ||
29 | + */ | ||
30 | + void deleteFlowRule(FlowRule rule); | ||
25 | 31 | ||
26 | /** | 32 | /** |
27 | * Stores a new flow rule, or updates an existing entry. | 33 | * Stores a new flow rule, or updates an existing entry. | ... | ... |
... | @@ -3,7 +3,6 @@ package org.onlab.onos.net.flow.impl; | ... | @@ -3,7 +3,6 @@ package org.onlab.onos.net.flow.impl; |
3 | import static com.google.common.base.Preconditions.checkNotNull; | 3 | import static com.google.common.base.Preconditions.checkNotNull; |
4 | import static org.slf4j.LoggerFactory.getLogger; | 4 | import static org.slf4j.LoggerFactory.getLogger; |
5 | 5 | ||
6 | -import java.util.ArrayList; | ||
7 | import java.util.Iterator; | 6 | import java.util.Iterator; |
8 | import java.util.List; | 7 | import java.util.List; |
9 | 8 | ||
... | @@ -73,18 +72,14 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -73,18 +72,14 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
73 | } | 72 | } |
74 | 73 | ||
75 | @Override | 74 | @Override |
76 | - public List<FlowRule> applyFlowRules(FlowRule... flowRules) { | 75 | + public void applyFlowRules(FlowRule... flowRules) { |
77 | - List<FlowRule> entries = new ArrayList<FlowRule>(); | ||
78 | - | ||
79 | for (int i = 0; i < flowRules.length; i++) { | 76 | for (int i = 0; i < flowRules.length; i++) { |
80 | FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD); | 77 | FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD); |
81 | final Device device = deviceService.getDevice(f.deviceId()); | 78 | final Device device = deviceService.getDevice(f.deviceId()); |
82 | final FlowRuleProvider frp = getProvider(device.providerId()); | 79 | final FlowRuleProvider frp = getProvider(device.providerId()); |
83 | - entries.add(store.storeFlowRule(f)); | 80 | + store.storeFlowRule(f); |
84 | frp.applyFlowRule(f); | 81 | frp.applyFlowRule(f); |
85 | } | 82 | } |
86 | - | ||
87 | - return entries; | ||
88 | } | 83 | } |
89 | 84 | ||
90 | @Override | 85 | @Override |
... | @@ -93,7 +88,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -93,7 +88,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
93 | FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE); | 88 | FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE); |
94 | final Device device = deviceService.getDevice(f.deviceId()); | 89 | final Device device = deviceService.getDevice(f.deviceId()); |
95 | final FlowRuleProvider frp = getProvider(device.providerId()); | 90 | final FlowRuleProvider frp = getProvider(device.providerId()); |
96 | - store.removeFlowRule(f); | 91 | + store.deleteFlowRule(f); |
97 | frp.removeFlowRule(f); | 92 | frp.removeFlowRule(f); |
98 | } | 93 | } |
99 | 94 | ||
... | @@ -139,22 +134,30 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -139,22 +134,30 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
139 | public void flowMissing(FlowRule flowRule) { | 134 | public void flowMissing(FlowRule flowRule) { |
140 | checkNotNull(flowRule, FLOW_RULE_NULL); | 135 | checkNotNull(flowRule, FLOW_RULE_NULL); |
141 | checkValidity(); | 136 | checkValidity(); |
142 | - // TODO Auto-generated method stub | 137 | + log.info("Flow {} has not been installed."); |
143 | 138 | ||
144 | } | 139 | } |
145 | 140 | ||
146 | @Override | 141 | @Override |
142 | + public void extraneousFlow(FlowRule flowRule) { | ||
143 | + checkNotNull(flowRule, FLOW_RULE_NULL); | ||
144 | + checkValidity(); | ||
145 | + log.info("Flow {} is on switch but not in store."); | ||
146 | + } | ||
147 | + | ||
148 | + @Override | ||
147 | public void flowAdded(FlowRule flowRule) { | 149 | public void flowAdded(FlowRule flowRule) { |
148 | checkNotNull(flowRule, FLOW_RULE_NULL); | 150 | checkNotNull(flowRule, FLOW_RULE_NULL); |
149 | checkValidity(); | 151 | checkValidity(); |
150 | 152 | ||
151 | FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule); | 153 | FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule); |
152 | if (event == null) { | 154 | if (event == null) { |
153 | - log.debug("Flow {} updated", flowRule); | 155 | + log.debug("No flow store event generated."); |
154 | } else { | 156 | } else { |
155 | - log.debug("Flow {} added", flowRule); | 157 | + log.debug("Flow {} {}", flowRule, event.type()); |
156 | post(event); | 158 | post(event); |
157 | } | 159 | } |
160 | + | ||
158 | } | 161 | } |
159 | 162 | ||
160 | // Posts the specified event to the local event dispatcher. | 163 | // Posts the specified event to the local event dispatcher. |
... | @@ -167,31 +170,23 @@ implements FlowRuleService, FlowRuleProviderRegistry { | ... | @@ -167,31 +170,23 @@ implements FlowRuleService, FlowRuleProviderRegistry { |
167 | @Override | 170 | @Override |
168 | public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) { | 171 | public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) { |
169 | List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId)); | 172 | List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId)); |
170 | - List<FlowRule> switchRules = Lists.newLinkedList(flowEntries); | 173 | + //List<FlowRule> switchRules = Lists.newLinkedList(flowEntries); |
171 | - Iterator<FlowRule> switchRulesIterator = switchRules.iterator(); | 174 | + Iterator<FlowRule> switchRulesIterator = flowEntries.iterator(); //switchRules.iterator(); |
172 | - List<FlowRule> extraRules = Lists.newLinkedList(); | ||
173 | 175 | ||
174 | while (switchRulesIterator.hasNext()) { | 176 | while (switchRulesIterator.hasNext()) { |
175 | FlowRule rule = switchRulesIterator.next(); | 177 | FlowRule rule = switchRulesIterator.next(); |
176 | if (storedRules.remove(rule)) { | 178 | if (storedRules.remove(rule)) { |
177 | - // we both have the rule let's update some info then. | 179 | + // 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 | flowAdded(rule); |
180 | } else { | 181 | } else { |
181 | - // the device a rule the store does not have | 182 | + // the device has a rule the store does not have |
182 | - extraRules.add(rule); | 183 | + extraneousFlow(rule); |
183 | } | 184 | } |
184 | } | 185 | } |
185 | for (FlowRule rule : storedRules) { | 186 | for (FlowRule rule : storedRules) { |
186 | // there are rules in the store that aren't on the switch | 187 | // there are rules in the store that aren't on the switch |
187 | flowMissing(rule); | 188 | flowMissing(rule); |
188 | } | 189 | } |
189 | - if (extraRules.size() > 0) { | ||
190 | - log.warn("Device {} has extra flow rules: {}", deviceId, extraRules); | ||
191 | - // TODO do something with this. | ||
192 | - } | ||
193 | - | ||
194 | - | ||
195 | } | 190 | } |
196 | } | 191 | } |
197 | 192 | ... | ... |
... | @@ -6,6 +6,7 @@ import static org.junit.Assert.assertNotNull; | ... | @@ -6,6 +6,7 @@ import static org.junit.Assert.assertNotNull; |
6 | import static org.junit.Assert.assertTrue; | 6 | import static org.junit.Assert.assertTrue; |
7 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED; | 7 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED; |
8 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; | 8 | import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; |
9 | +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED; | ||
9 | 10 | ||
10 | import java.util.ArrayList; | 11 | import java.util.ArrayList; |
11 | import java.util.List; | 12 | import java.util.List; |
... | @@ -37,10 +38,10 @@ import org.onlab.onos.net.flow.criteria.Criterion; | ... | @@ -37,10 +38,10 @@ import org.onlab.onos.net.flow.criteria.Criterion; |
37 | import org.onlab.onos.net.flow.instructions.Instruction; | 38 | import org.onlab.onos.net.flow.instructions.Instruction; |
38 | import org.onlab.onos.net.provider.AbstractProvider; | 39 | import org.onlab.onos.net.provider.AbstractProvider; |
39 | import org.onlab.onos.net.provider.ProviderId; | 40 | import org.onlab.onos.net.provider.ProviderId; |
41 | +import org.onlab.onos.net.trivial.impl.SimpleFlowRuleStore; | ||
40 | 42 | ||
41 | import com.google.common.collect.Lists; | 43 | import com.google.common.collect.Lists; |
42 | import com.google.common.collect.Sets; | 44 | import com.google.common.collect.Sets; |
43 | -import org.onlab.onos.net.trivial.impl.SimpleFlowRuleStore; | ||
44 | 45 | ||
45 | /** | 46 | /** |
46 | * Test codifying the flow rule service & flow rule provider service contracts. | 47 | * Test codifying the flow rule service & flow rule provider service contracts. |
... | @@ -131,7 +132,7 @@ public class FlowRuleManagerTest { | ... | @@ -131,7 +132,7 @@ public class FlowRuleManagerTest { |
131 | 132 | ||
132 | addFlowRule(1); | 133 | addFlowRule(1); |
133 | assertEquals("should still be 2 rules", 2, flowCount()); | 134 | assertEquals("should still be 2 rules", 2, flowCount()); |
134 | - validateEvents(); | 135 | + validateEvents(RULE_UPDATED); |
135 | } | 136 | } |
136 | 137 | ||
137 | @Test | 138 | @Test |
... | @@ -149,9 +150,9 @@ public class FlowRuleManagerTest { | ... | @@ -149,9 +150,9 @@ public class FlowRuleManagerTest { |
149 | 150 | ||
150 | assertTrue("store should be empty", | 151 | assertTrue("store should be empty", |
151 | Sets.newHashSet(service.getFlowEntries(DID)).isEmpty()); | 152 | Sets.newHashSet(service.getFlowEntries(DID)).isEmpty()); |
152 | - List<FlowRule> ret = mgr.applyFlowRules(r1, r2, r3); | 153 | + mgr.applyFlowRules(r1, r2, r3); |
153 | assertEquals("3 rules should exist", 3, flowCount()); | 154 | assertEquals("3 rules should exist", 3, flowCount()); |
154 | - assertTrue("3 entries should result", fel.containsAll(ret)); | 155 | + assertTrue("3 entries should result", fel.containsAll(Lists.newArrayList(r1, r2, r3))); |
155 | } | 156 | } |
156 | 157 | ||
157 | @Test | 158 | @Test |
... | @@ -167,10 +168,10 @@ public class FlowRuleManagerTest { | ... | @@ -167,10 +168,10 @@ public class FlowRuleManagerTest { |
167 | mgr.removeFlowRules(rem1, rem2); | 168 | mgr.removeFlowRules(rem1, rem2); |
168 | //removing from north, so no events generated | 169 | //removing from north, so no events generated |
169 | validateEvents(); | 170 | validateEvents(); |
170 | - assertEquals("1 rule should exist", 1, flowCount()); | 171 | + assertEquals("3 rule should exist", 3, flowCount()); |
171 | 172 | ||
172 | mgr.removeFlowRules(rem1); | 173 | mgr.removeFlowRules(rem1); |
173 | - assertEquals("1 rule should still exist", 1, flowCount()); | 174 | + assertEquals("3 rule should still exist", 3, flowCount()); |
174 | } | 175 | } |
175 | 176 | ||
176 | @Test | 177 | @Test | ... | ... |
1 | package org.onlab.onos.net.trivial.impl; | 1 | package org.onlab.onos.net.trivial.impl; |
2 | 2 | ||
3 | -import com.google.common.collect.HashMultimap; | 3 | +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED; |
4 | -import com.google.common.collect.ImmutableSet; | 4 | +import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; |
5 | -import com.google.common.collect.Multimap; | 5 | +import static org.slf4j.LoggerFactory.getLogger; |
6 | + | ||
6 | import org.apache.felix.scr.annotations.Activate; | 7 | import org.apache.felix.scr.annotations.Activate; |
7 | import org.apache.felix.scr.annotations.Component; | 8 | import org.apache.felix.scr.annotations.Component; |
8 | import org.apache.felix.scr.annotations.Deactivate; | 9 | import org.apache.felix.scr.annotations.Deactivate; |
9 | import org.apache.felix.scr.annotations.Service; | 10 | import org.apache.felix.scr.annotations.Service; |
10 | import org.onlab.onos.net.DeviceId; | 11 | import org.onlab.onos.net.DeviceId; |
11 | -import org.onlab.onos.net.flow.DefaultFlowRule; | ||
12 | import org.onlab.onos.net.flow.FlowRule; | 12 | import org.onlab.onos.net.flow.FlowRule; |
13 | import org.onlab.onos.net.flow.FlowRuleEvent; | 13 | import org.onlab.onos.net.flow.FlowRuleEvent; |
14 | +import org.onlab.onos.net.flow.FlowRuleEvent.Type; | ||
14 | import org.onlab.onos.net.flow.FlowRuleStore; | 15 | import org.onlab.onos.net.flow.FlowRuleStore; |
15 | import org.slf4j.Logger; | 16 | import org.slf4j.Logger; |
16 | 17 | ||
17 | -import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED; | 18 | +import com.google.common.collect.ArrayListMultimap; |
18 | -import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; | 19 | +import com.google.common.collect.ImmutableSet; |
19 | -import static org.slf4j.LoggerFactory.getLogger; | 20 | +import com.google.common.collect.Multimap; |
20 | 21 | ||
21 | /** | 22 | /** |
22 | * Manages inventory of flow rules using trivial in-memory implementation. | 23 | * Manages inventory of flow rules using trivial in-memory implementation. |
... | @@ -28,7 +29,7 @@ public class SimpleFlowRuleStore implements FlowRuleStore { | ... | @@ -28,7 +29,7 @@ public class SimpleFlowRuleStore implements FlowRuleStore { |
28 | private final Logger log = getLogger(getClass()); | 29 | private final Logger log = getLogger(getClass()); |
29 | 30 | ||
30 | // store entries as a pile of rules, no info about device tables | 31 | // store entries as a pile of rules, no info about device tables |
31 | - private final Multimap<DeviceId, FlowRule> flowEntries = HashMultimap.create(); | 32 | + private final Multimap<DeviceId, FlowRule> flowEntries = ArrayListMultimap.create(); |
32 | 33 | ||
33 | @Activate | 34 | @Activate |
34 | public void activate() { | 35 | public void activate() { |
... | @@ -46,12 +47,26 @@ public class SimpleFlowRuleStore implements FlowRuleStore { | ... | @@ -46,12 +47,26 @@ public class SimpleFlowRuleStore implements FlowRuleStore { |
46 | } | 47 | } |
47 | 48 | ||
48 | @Override | 49 | @Override |
49 | - public FlowRule storeFlowRule(FlowRule rule) { | 50 | + public void storeFlowRule(FlowRule rule) { |
50 | DeviceId did = rule.deviceId(); | 51 | DeviceId did = rule.deviceId(); |
51 | - FlowRule entry = new DefaultFlowRule(did, | 52 | + flowEntries.put(did, rule); |
52 | - rule.selector(), rule.treatment(), rule.priority()); | 53 | + } |
53 | - flowEntries.put(did, entry); | 54 | + |
54 | - return entry; | 55 | + @Override |
56 | + public void deleteFlowRule(FlowRule rule) { | ||
57 | + DeviceId did = rule.deviceId(); | ||
58 | + | ||
59 | + /* | ||
60 | + * find the rule and mark it for deletion. | ||
61 | + * Ultimately a flow removed will come remove it. | ||
62 | + */ | ||
63 | + if (flowEntries.containsEntry(did, rule)) { | ||
64 | + synchronized (flowEntries) { | ||
65 | + | ||
66 | + flowEntries.remove(did, rule); | ||
67 | + flowEntries.put(did, rule); | ||
68 | + } | ||
69 | + } | ||
55 | } | 70 | } |
56 | 71 | ||
57 | @Override | 72 | @Override |
... | @@ -59,12 +74,17 @@ public class SimpleFlowRuleStore implements FlowRuleStore { | ... | @@ -59,12 +74,17 @@ public class SimpleFlowRuleStore implements FlowRuleStore { |
59 | DeviceId did = rule.deviceId(); | 74 | DeviceId did = rule.deviceId(); |
60 | 75 | ||
61 | // check if this new rule is an update to an existing entry | 76 | // check if this new rule is an update to an existing entry |
62 | - for (FlowRule fe : flowEntries.get(did)) { | 77 | + if (flowEntries.containsEntry(did, rule)) { |
63 | - if (rule.equals(fe)) { | 78 | + synchronized (flowEntries) { |
64 | - // TODO update the stats on this FlowRule? | 79 | + // Multimaps support duplicates so we have to remove our rule |
65 | - return null; | 80 | + // and replace it with the current version. |
81 | + | ||
82 | + flowEntries.remove(did, rule); | ||
83 | + flowEntries.put(did, rule); | ||
66 | } | 84 | } |
85 | + return new FlowRuleEvent(Type.RULE_UPDATED, rule); | ||
67 | } | 86 | } |
87 | + | ||
68 | flowEntries.put(did, rule); | 88 | flowEntries.put(did, rule); |
69 | return new FlowRuleEvent(RULE_ADDED, rule); | 89 | return new FlowRuleEvent(RULE_ADDED, rule); |
70 | } | 90 | } |
... | @@ -80,4 +100,6 @@ public class SimpleFlowRuleStore implements FlowRuleStore { | ... | @@ -80,4 +100,6 @@ public class SimpleFlowRuleStore implements FlowRuleStore { |
80 | } | 100 | } |
81 | } | 101 | } |
82 | 102 | ||
103 | + | ||
104 | + | ||
83 | } | 105 | } | ... | ... |
... | @@ -88,6 +88,24 @@ public class FlowModBuilder { | ... | @@ -88,6 +88,24 @@ public class FlowModBuilder { |
88 | 88 | ||
89 | } | 89 | } |
90 | 90 | ||
91 | + public OFFlowMod buildFlowDel() { | ||
92 | + Match match = buildMatch(); | ||
93 | + List<OFAction> actions = buildActions(); | ||
94 | + | ||
95 | + OFFlowMod fm = factory.buildFlowDelete() | ||
96 | + .setCookie(U64.of(cookie.value())) | ||
97 | + .setBufferId(OFBufferId.NO_BUFFER) | ||
98 | + .setActions(actions) | ||
99 | + .setMatch(match) | ||
100 | + .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) | ||
101 | + .setIdleTimeout(10) | ||
102 | + .setHardTimeout(10) | ||
103 | + .setPriority(priority) | ||
104 | + .build(); | ||
105 | + | ||
106 | + return fm; | ||
107 | + } | ||
108 | + | ||
91 | private List<OFAction> buildActions() { | 109 | private List<OFAction> buildActions() { |
92 | List<OFAction> acts = new LinkedList<>(); | 110 | List<OFAction> acts = new LinkedList<>(); |
93 | for (Instruction i : treatment.instructions()) { | 111 | for (Instruction i : treatment.instructions()) { |
... | @@ -246,4 +264,6 @@ public class FlowModBuilder { | ... | @@ -246,4 +264,6 @@ public class FlowModBuilder { |
246 | return mBuilder.build(); | 264 | return mBuilder.build(); |
247 | } | 265 | } |
248 | 266 | ||
267 | + | ||
268 | + | ||
249 | } | 269 | } | ... | ... |
... | @@ -53,7 +53,7 @@ public class FlowRuleBuilder { | ... | @@ -53,7 +53,7 @@ public class FlowRuleBuilder { |
53 | this.match = entry.getMatch(); | 53 | this.match = entry.getMatch(); |
54 | this.actions = entry.getActions(); | 54 | this.actions = entry.getActions(); |
55 | this.dpid = dpid; | 55 | this.dpid = dpid; |
56 | - removed = null; | 56 | + this.removed = null; |
57 | } | 57 | } |
58 | 58 | ||
59 | public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) { | 59 | public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) { |
... | @@ -72,14 +72,14 @@ public class FlowRuleBuilder { | ... | @@ -72,14 +72,14 @@ public class FlowRuleBuilder { |
72 | buildSelector(), buildTreatment(), stat.getPriority(), | 72 | buildSelector(), buildTreatment(), stat.getPriority(), |
73 | FlowRuleState.ADDED, stat.getDurationNsec() / 1000000, | 73 | FlowRuleState.ADDED, stat.getDurationNsec() / 1000000, |
74 | stat.getPacketCount().getValue(), stat.getByteCount().getValue(), | 74 | stat.getPacketCount().getValue(), stat.getByteCount().getValue(), |
75 | - (int) (stat.getCookie().getValue() & 0xFFFFFFFF)); | 75 | + stat.getCookie().getValue()); |
76 | } else { | 76 | } else { |
77 | // TODO: revisit potentially. | 77 | // TODO: revisit potentially. |
78 | return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), | 78 | return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), |
79 | buildSelector(), null, removed.getPriority(), | 79 | buildSelector(), null, removed.getPriority(), |
80 | FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000, | 80 | FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000, |
81 | removed.getPacketCount().getValue(), removed.getByteCount().getValue(), | 81 | removed.getPacketCount().getValue(), removed.getByteCount().getValue(), |
82 | - (int) (removed.getCookie().getValue() & 0xFFFFFFFF)); | 82 | + removed.getCookie().getValue()); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ... | ... |
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
... | @@ -95,8 +95,16 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -95,8 +95,16 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr |
95 | 95 | ||
96 | @Override | 96 | @Override |
97 | public void removeFlowRule(FlowRule... flowRules) { | 97 | public void removeFlowRule(FlowRule... flowRules) { |
98 | - // TODO Auto-generated method stub | 98 | + for (int i = 0; i < flowRules.length; i++) { |
99 | + removeRule(flowRules[i]); | ||
100 | + } | ||
101 | + | ||
102 | + } | ||
103 | + | ||
99 | 104 | ||
105 | + private void removeRule(FlowRule flowRule) { | ||
106 | + OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri())); | ||
107 | + sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowDel()); | ||
100 | } | 108 | } |
101 | 109 | ||
102 | 110 | ||
... | @@ -109,7 +117,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -109,7 +117,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr |
109 | 117 | ||
110 | @Override | 118 | @Override |
111 | public void switchAdded(Dpid dpid) { | 119 | public void switchAdded(Dpid dpid) { |
112 | - FlowStatsCollector fsc = new FlowStatsCollector(controller.getSwitch(dpid), 1); | 120 | + FlowStatsCollector fsc = new FlowStatsCollector(controller.getSwitch(dpid), 5); |
113 | fsc.start(); | 121 | fsc.start(); |
114 | collectors.put(dpid, fsc); | 122 | collectors.put(dpid, fsc); |
115 | } | 123 | } | ... | ... |
-
Please register or login to post a comment