alshabib

flowrule states functional

Change-Id: Id310f146d4ef2a59993f31d60062464a24df4560
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) {
51 + DeviceId did = rule.deviceId();
52 + flowEntries.put(did, rule);
53 + }
54 +
55 + @Override
56 + public void deleteFlowRule(FlowRule rule) {
50 DeviceId did = rule.deviceId(); 57 DeviceId did = rule.deviceId();
51 - FlowRule entry = new DefaultFlowRule(did, 58 +
52 - rule.selector(), rule.treatment(), rule.priority()); 59 + /*
53 - flowEntries.put(did, entry); 60 + * find the rule and mark it for deletion.
54 - return entry; 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
......
...@@ -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 }
......