alshabib

flowrules no longer install a timeout but are monitored by onos in order to be expired

Change-Id: Ibd1a5952349d7ccb27c92b4982d04574f31424c0
...@@ -38,6 +38,8 @@ import org.slf4j.Logger; ...@@ -38,6 +38,8 @@ import org.slf4j.Logger;
38 @Component(immediate = true) 38 @Component(immediate = true)
39 public class ReactiveForwarding { 39 public class ReactiveForwarding {
40 40
41 + private static final int TIMEOUT = 10;
42 +
41 private final Logger log = getLogger(getClass()); 43 private final Logger log = getLogger(getClass());
42 44
43 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
...@@ -192,7 +194,7 @@ public class ReactiveForwarding { ...@@ -192,7 +194,7 @@ public class ReactiveForwarding {
192 treat.setOutput(portNumber); 194 treat.setOutput(portNumber);
193 195
194 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(), 196 FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
195 - builder.build(), treat.build(), 0, appId); 197 + builder.build(), treat.build(), 0, appId, TIMEOUT);
196 198
197 flowRuleService.applyFlowRules(f); 199 flowRuleService.applyFlowRules(f);
198 } 200 }
......
...@@ -27,11 +27,12 @@ public class DefaultFlowRule implements FlowRule { ...@@ -27,11 +27,12 @@ public class DefaultFlowRule implements FlowRule {
27 27
28 private final ApplicationId appId; 28 private final ApplicationId appId;
29 29
30 - private boolean expired; 30 + private final int timeout;
31 31
32 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 32 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
33 TrafficTreatment treatment, int priority, FlowRuleState state, 33 TrafficTreatment treatment, int priority, FlowRuleState state,
34 - long life, long packets, long bytes, long flowId, boolean expired) { 34 + long life, long packets, long bytes, long flowId, boolean expired,
35 + int timeout) {
35 this.deviceId = deviceId; 36 this.deviceId = deviceId;
36 this.priority = priority; 37 this.priority = priority;
37 this.selector = selector; 38 this.selector = selector;
...@@ -39,26 +40,30 @@ public class DefaultFlowRule implements FlowRule { ...@@ -39,26 +40,30 @@ public class DefaultFlowRule implements FlowRule {
39 this.state = state; 40 this.state = state;
40 this.appId = ApplicationId.valueOf((int) (flowId >> 32)); 41 this.appId = ApplicationId.valueOf((int) (flowId >> 32));
41 this.id = FlowId.valueOf(flowId); 42 this.id = FlowId.valueOf(flowId);
42 - this.expired = expired;
43 this.life = life; 43 this.life = life;
44 this.packets = packets; 44 this.packets = packets;
45 this.bytes = bytes; 45 this.bytes = bytes;
46 this.created = System.currentTimeMillis(); 46 this.created = System.currentTimeMillis();
47 + this.timeout = timeout;
47 } 48 }
48 49
49 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 50 public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
50 - TrafficTreatment treatement, int priority, ApplicationId appId) { 51 + TrafficTreatment treatement, int priority, ApplicationId appId,
51 - this(deviceId, selector, treatement, priority, FlowRuleState.CREATED, appId); 52 + int timeout) {
53 + this(deviceId, selector, treatement, priority,
54 + FlowRuleState.CREATED, appId, timeout);
52 } 55 }
53 56
54 public DefaultFlowRule(FlowRule rule, FlowRuleState state) { 57 public DefaultFlowRule(FlowRule rule, FlowRuleState state) {
55 this(rule.deviceId(), rule.selector(), rule.treatment(), 58 this(rule.deviceId(), rule.selector(), rule.treatment(),
56 - rule.priority(), state, rule.id(), rule.appId()); 59 + rule.priority(), state, rule.id(), rule.appId(),
60 + rule.timeout());
57 } 61 }
58 62
59 private DefaultFlowRule(DeviceId deviceId, 63 private DefaultFlowRule(DeviceId deviceId,
60 TrafficSelector selector, TrafficTreatment treatment, 64 TrafficSelector selector, TrafficTreatment treatment,
61 - int priority, FlowRuleState state, ApplicationId appId) { 65 + int priority, FlowRuleState state, ApplicationId appId,
66 + int timeout) {
62 this.deviceId = deviceId; 67 this.deviceId = deviceId;
63 this.priority = priority; 68 this.priority = priority;
64 this.selector = selector; 69 this.selector = selector;
...@@ -69,13 +74,16 @@ public class DefaultFlowRule implements FlowRule { ...@@ -69,13 +74,16 @@ public class DefaultFlowRule implements FlowRule {
69 this.bytes = 0; 74 this.bytes = 0;
70 this.appId = appId; 75 this.appId = appId;
71 76
77 + this.timeout = timeout;
78 +
72 this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL)); 79 this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL));
73 this.created = System.currentTimeMillis(); 80 this.created = System.currentTimeMillis();
74 } 81 }
75 82
76 private DefaultFlowRule(DeviceId deviceId, 83 private DefaultFlowRule(DeviceId deviceId,
77 TrafficSelector selector, TrafficTreatment treatment, 84 TrafficSelector selector, TrafficTreatment treatment,
78 - int priority, FlowRuleState state, FlowId flowId, ApplicationId appId) { 85 + int priority, FlowRuleState state, FlowId flowId, ApplicationId appId,
86 + int timeout) {
79 this.deviceId = deviceId; 87 this.deviceId = deviceId;
80 this.priority = priority; 88 this.priority = priority;
81 this.selector = selector; 89 this.selector = selector;
...@@ -86,6 +94,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -86,6 +94,7 @@ public class DefaultFlowRule implements FlowRule {
86 this.bytes = 0; 94 this.bytes = 0;
87 this.appId = appId; 95 this.appId = appId;
88 this.id = flowId; 96 this.id = flowId;
97 + this.timeout = timeout;
89 this.created = System.currentTimeMillis(); 98 this.created = System.currentTimeMillis();
90 } 99 }
91 100
...@@ -149,7 +158,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -149,7 +158,7 @@ public class DefaultFlowRule implements FlowRule {
149 * @see java.lang.Object#equals(java.lang.Object) 158 * @see java.lang.Object#equals(java.lang.Object)
150 */ 159 */
151 public int hashCode() { 160 public int hashCode() {
152 - return Objects.hash(deviceId, id); 161 + return Objects.hash(deviceId, selector, priority);
153 } 162 }
154 163
155 public int hash() { 164 public int hash() {
...@@ -170,7 +179,10 @@ public class DefaultFlowRule implements FlowRule { ...@@ -170,7 +179,10 @@ public class DefaultFlowRule implements FlowRule {
170 if (obj instanceof DefaultFlowRule) { 179 if (obj instanceof DefaultFlowRule) {
171 DefaultFlowRule that = (DefaultFlowRule) obj; 180 DefaultFlowRule that = (DefaultFlowRule) obj;
172 return Objects.equals(deviceId, that.deviceId) && 181 return Objects.equals(deviceId, that.deviceId) &&
173 - Objects.equals(id, that.id); 182 + //Objects.equals(id, that.id) &&
183 + Objects.equals(priority, that.priority) &&
184 + Objects.equals(selector, that.selector);
185 +
174 } 186 }
175 return false; 187 return false;
176 } 188 }
...@@ -181,16 +193,16 @@ public class DefaultFlowRule implements FlowRule { ...@@ -181,16 +193,16 @@ public class DefaultFlowRule implements FlowRule {
181 .add("id", id) 193 .add("id", id)
182 .add("deviceId", deviceId) 194 .add("deviceId", deviceId)
183 .add("priority", priority) 195 .add("priority", priority)
184 - .add("selector", selector) 196 + .add("selector", selector.criteria())
185 - .add("treatment", treatment) 197 + .add("treatment", treatment == null ? "N/A" : treatment.instructions())
186 .add("created", created) 198 .add("created", created)
187 .add("state", state) 199 .add("state", state)
188 .toString(); 200 .toString();
189 } 201 }
190 202
191 @Override 203 @Override
192 - public boolean expired() { 204 + public int timeout() {
193 - return expired; 205 + return timeout > MAX_TIMEOUT ? MAX_TIMEOUT : this.timeout;
194 } 206 }
195 207
196 } 208 }
......
...@@ -3,8 +3,9 @@ package org.onlab.onos.net.flow; ...@@ -3,8 +3,9 @@ package org.onlab.onos.net.flow;
3 import static org.slf4j.LoggerFactory.getLogger; 3 import static org.slf4j.LoggerFactory.getLogger;
4 4
5 import java.util.Collections; 5 import java.util.Collections;
6 -import java.util.LinkedList; 6 +import java.util.HashSet;
7 -import java.util.List; 7 +import java.util.Objects;
8 +import java.util.Set;
8 9
9 import org.onlab.onos.net.PortNumber; 10 import org.onlab.onos.net.PortNumber;
10 import org.onlab.onos.net.flow.criteria.Criteria; 11 import org.onlab.onos.net.flow.criteria.Criteria;
...@@ -16,22 +17,42 @@ import org.slf4j.Logger; ...@@ -16,22 +17,42 @@ import org.slf4j.Logger;
16 17
17 public final class DefaultTrafficSelector implements TrafficSelector { 18 public final class DefaultTrafficSelector implements TrafficSelector {
18 19
19 - private final List<Criterion> selector; 20 + private final Set<Criterion> selector;
20 21
21 - private DefaultTrafficSelector(List<Criterion> selector) { 22 + private DefaultTrafficSelector(Set<Criterion> selector) {
22 - this.selector = Collections.unmodifiableList(selector); 23 + this.selector = Collections.unmodifiableSet(selector);
23 } 24 }
24 25
25 @Override 26 @Override
26 - public List<Criterion> criteria() { 27 + public Set<Criterion> criteria() {
27 return selector; 28 return selector;
28 } 29 }
29 30
31 + @Override
32 + public int hashCode() {
33 + return Objects.hash(selector);
34 + }
35 +
36 + @Override
37 + public boolean equals(Object obj) {
38 + if (this == obj) {
39 + return true;
40 + }
41 + if (obj instanceof DefaultTrafficSelector) {
42 + DefaultTrafficSelector that = (DefaultTrafficSelector) obj;
43 + return Objects.equals(selector, that.selector);
44 +
45 + }
46 + return false;
47 + }
48 +
49 +
50 +
30 public static class Builder implements TrafficSelector.Builder { 51 public static class Builder implements TrafficSelector.Builder {
31 52
32 private final Logger log = getLogger(getClass()); 53 private final Logger log = getLogger(getClass());
33 54
34 - private final List<Criterion> selector = new LinkedList<>(); 55 + private final Set<Criterion> selector = new HashSet<>();
35 56
36 @Override 57 @Override
37 public Builder add(Criterion criterion) { 58 public Builder add(Criterion criterion) {
...@@ -39,38 +60,47 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -39,38 +60,47 @@ public final class DefaultTrafficSelector implements TrafficSelector {
39 return this; 60 return this;
40 } 61 }
41 62
63 + @Override
42 public Builder matchInport(PortNumber port) { 64 public Builder matchInport(PortNumber port) {
43 return add(Criteria.matchInPort(port)); 65 return add(Criteria.matchInPort(port));
44 } 66 }
45 67
68 + @Override
46 public Builder matchEthSrc(MacAddress addr) { 69 public Builder matchEthSrc(MacAddress addr) {
47 return add(Criteria.matchEthSrc(addr)); 70 return add(Criteria.matchEthSrc(addr));
48 } 71 }
49 72
73 + @Override
50 public Builder matchEthDst(MacAddress addr) { 74 public Builder matchEthDst(MacAddress addr) {
51 return add(Criteria.matchEthDst(addr)); 75 return add(Criteria.matchEthDst(addr));
52 } 76 }
53 77
78 + @Override
54 public Builder matchEthType(short ethType) { 79 public Builder matchEthType(short ethType) {
55 return add(Criteria.matchEthType(ethType)); 80 return add(Criteria.matchEthType(ethType));
56 } 81 }
57 82
83 + @Override
58 public Builder matchVlanId(VlanId vlanId) { 84 public Builder matchVlanId(VlanId vlanId) {
59 return add(Criteria.matchVlanId(vlanId)); 85 return add(Criteria.matchVlanId(vlanId));
60 } 86 }
61 87
88 + @Override
62 public Builder matchVlanPcp(Byte vlanPcp) { 89 public Builder matchVlanPcp(Byte vlanPcp) {
63 return add(Criteria.matchVlanPcp(vlanPcp)); 90 return add(Criteria.matchVlanPcp(vlanPcp));
64 } 91 }
65 92
93 + @Override
66 public Builder matchIPProtocol(Byte proto) { 94 public Builder matchIPProtocol(Byte proto) {
67 return add(Criteria.matchIPProtocol(proto)); 95 return add(Criteria.matchIPProtocol(proto));
68 } 96 }
69 97
98 + @Override
70 public Builder matchIPSrc(IpPrefix ip) { 99 public Builder matchIPSrc(IpPrefix ip) {
71 return add(Criteria.matchIPSrc(ip)); 100 return add(Criteria.matchIPSrc(ip));
72 } 101 }
73 102
103 + @Override
74 public Builder matchIPDst(IpPrefix ip) { 104 public Builder matchIPDst(IpPrefix ip) {
75 return add(Criteria.matchIPDst(ip)); 105 return add(Criteria.matchIPDst(ip));
76 } 106 }
......
...@@ -9,6 +9,7 @@ import org.onlab.onos.net.DeviceId; ...@@ -9,6 +9,7 @@ import org.onlab.onos.net.DeviceId;
9 */ 9 */
10 public interface FlowRule { 10 public interface FlowRule {
11 11
12 + static final int MAX_TIMEOUT = 60;
12 13
13 public enum FlowRuleState { 14 public enum FlowRuleState {
14 /** 15 /**
...@@ -112,10 +113,9 @@ public interface FlowRule { ...@@ -112,10 +113,9 @@ public interface FlowRule {
112 long bytes(); 113 long bytes();
113 114
114 /** 115 /**
115 - * Indicates that this flow has expired at the device. 116 + * Returns the timeout for this flow requested by an application.
116 - * 117 + * @return integer value of the timeout
117 - * @return true if it has expired, false otherwise
118 */ 118 */
119 - boolean expired(); 119 + int timeout();
120 120
121 } 121 }
......
...@@ -8,6 +8,8 @@ import org.onlab.onos.net.provider.Provider; ...@@ -8,6 +8,8 @@ import org.onlab.onos.net.provider.Provider;
8 */ 8 */
9 public interface FlowRuleProvider extends Provider { 9 public interface FlowRuleProvider extends Provider {
10 10
11 + static final int POLL_INTERVAL = 5;
12 +
11 /** 13 /**
12 * Instructs the provider to apply the specified flow rules to their 14 * Instructs the provider to apply the specified flow rules to their
13 * respective devices. 15 * respective devices.
......
...@@ -17,27 +17,6 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide ...@@ -17,27 +17,6 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide
17 void flowRemoved(FlowRule flowRule); 17 void flowRemoved(FlowRule flowRule);
18 18
19 /** 19 /**
20 - * Signals that a flow rule is missing for some network traffic.
21 - *
22 - * @param flowRule information about traffic in need of flow rule(s)
23 - */
24 - void flowMissing(FlowRule flowRule);
25 -
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 - /**
34 - * Signals that a flow rule was indeed added.
35 - *
36 - * @param flowRule the added flow rule
37 - */
38 - void flowAdded(FlowRule flowRule);
39 -
40 - /**
41 * Pushes the collection of flow entries currently applied on the given 20 * Pushes the collection of flow entries currently applied on the given
42 * device. 21 * device.
43 * 22 *
......
1 package org.onlab.onos.net.flow; 1 package org.onlab.onos.net.flow;
2 2
3 -import java.util.List; 3 +import java.util.Set;
4 4
5 import org.onlab.onos.net.PortNumber; 5 import org.onlab.onos.net.PortNumber;
6 import org.onlab.onos.net.flow.criteria.Criterion; 6 import org.onlab.onos.net.flow.criteria.Criterion;
...@@ -18,7 +18,7 @@ public interface TrafficSelector { ...@@ -18,7 +18,7 @@ public interface TrafficSelector {
18 * 18 *
19 * @return list of criteria 19 * @return list of criteria
20 */ 20 */
21 - List<Criterion> criteria(); 21 + Set<Criterion> criteria();
22 22
23 /** 23 /**
24 * Builder of traffic selector entities. 24 * Builder of traffic selector entities.
......
...@@ -2,6 +2,8 @@ package org.onlab.onos.net.flow.criteria; ...@@ -2,6 +2,8 @@ package org.onlab.onos.net.flow.criteria;
2 2
3 import static com.google.common.base.MoreObjects.toStringHelper; 3 import static com.google.common.base.MoreObjects.toStringHelper;
4 4
5 +import java.util.Objects;
6 +
5 import org.onlab.onos.net.PortNumber; 7 import org.onlab.onos.net.PortNumber;
6 import org.onlab.onos.net.flow.criteria.Criterion.Type; 8 import org.onlab.onos.net.flow.criteria.Criterion.Type;
7 import org.onlab.packet.IpPrefix; 9 import org.onlab.packet.IpPrefix;
...@@ -137,6 +139,25 @@ public final class Criteria { ...@@ -137,6 +139,25 @@ public final class Criteria {
137 return toStringHelper(type().toString()) 139 return toStringHelper(type().toString())
138 .add("port", port).toString(); 140 .add("port", port).toString();
139 } 141 }
142 +
143 + @Override
144 + public int hashCode() {
145 + return Objects.hash(port);
146 + }
147 +
148 + @Override
149 + public boolean equals(Object obj) {
150 + if (this == obj) {
151 + return true;
152 + }
153 + if (obj instanceof PortCriterion) {
154 + PortCriterion that = (PortCriterion) obj;
155 + return Objects.equals(port, that.port);
156 +
157 + }
158 + return false;
159 + }
160 +
140 } 161 }
141 162
142 163
...@@ -164,6 +185,27 @@ public final class Criteria { ...@@ -164,6 +185,27 @@ public final class Criteria {
164 .add("mac", mac).toString(); 185 .add("mac", mac).toString();
165 } 186 }
166 187
188 + @Override
189 + public int hashCode() {
190 + return Objects.hash(mac, type);
191 + }
192 +
193 + @Override
194 + public boolean equals(Object obj) {
195 + if (this == obj) {
196 + return true;
197 + }
198 + if (obj instanceof EthCriterion) {
199 + EthCriterion that = (EthCriterion) obj;
200 + return Objects.equals(mac, that.mac) &&
201 + Objects.equals(type, that.type);
202 +
203 +
204 + }
205 + return false;
206 + }
207 +
208 +
167 } 209 }
168 210
169 public static final class EthTypeCriterion implements Criterion { 211 public static final class EthTypeCriterion implements Criterion {
...@@ -189,6 +231,25 @@ public final class Criteria { ...@@ -189,6 +231,25 @@ public final class Criteria {
189 .add("ethType", Long.toHexString(ethType)).toString(); 231 .add("ethType", Long.toHexString(ethType)).toString();
190 } 232 }
191 233
234 + @Override
235 + public int hashCode() {
236 + return Objects.hash(ethType);
237 + }
238 +
239 + @Override
240 + public boolean equals(Object obj) {
241 + if (this == obj) {
242 + return true;
243 + }
244 + if (obj instanceof EthTypeCriterion) {
245 + EthTypeCriterion that = (EthTypeCriterion) obj;
246 + return Objects.equals(ethType, that.ethType);
247 +
248 +
249 + }
250 + return false;
251 + }
252 +
192 } 253 }
193 254
194 255
...@@ -217,6 +278,26 @@ public final class Criteria { ...@@ -217,6 +278,26 @@ public final class Criteria {
217 .add("ip", ip).toString(); 278 .add("ip", ip).toString();
218 } 279 }
219 280
281 + @Override
282 + public int hashCode() {
283 + return Objects.hash(ip, type);
284 + }
285 +
286 + @Override
287 + public boolean equals(Object obj) {
288 + if (this == obj) {
289 + return true;
290 + }
291 + if (obj instanceof IPCriterion) {
292 + IPCriterion that = (IPCriterion) obj;
293 + return Objects.equals(ip, that.ip) &&
294 + Objects.equals(type, that.type);
295 +
296 +
297 + }
298 + return false;
299 + }
300 +
220 } 301 }
221 302
222 303
...@@ -243,6 +324,25 @@ public final class Criteria { ...@@ -243,6 +324,25 @@ public final class Criteria {
243 .add("protocol", Long.toHexString(proto)).toString(); 324 .add("protocol", Long.toHexString(proto)).toString();
244 } 325 }
245 326
327 + @Override
328 + public int hashCode() {
329 + return Objects.hash(proto);
330 + }
331 +
332 + @Override
333 + public boolean equals(Object obj) {
334 + if (this == obj) {
335 + return true;
336 + }
337 + if (obj instanceof IPProtocolCriterion) {
338 + IPProtocolCriterion that = (IPProtocolCriterion) obj;
339 + return Objects.equals(proto, that.proto);
340 +
341 +
342 + }
343 + return false;
344 + }
345 +
246 } 346 }
247 347
248 348
...@@ -269,6 +369,25 @@ public final class Criteria { ...@@ -269,6 +369,25 @@ public final class Criteria {
269 .add("pcp", Long.toHexString(vlanPcp)).toString(); 369 .add("pcp", Long.toHexString(vlanPcp)).toString();
270 } 370 }
271 371
372 + @Override
373 + public int hashCode() {
374 + return Objects.hash(vlanPcp);
375 + }
376 +
377 + @Override
378 + public boolean equals(Object obj) {
379 + if (this == obj) {
380 + return true;
381 + }
382 + if (obj instanceof VlanPcpCriterion) {
383 + VlanPcpCriterion that = (VlanPcpCriterion) obj;
384 + return Objects.equals(vlanPcp, that.vlanPcp);
385 +
386 +
387 + }
388 + return false;
389 + }
390 +
272 } 391 }
273 392
274 393
...@@ -296,6 +415,25 @@ public final class Criteria { ...@@ -296,6 +415,25 @@ public final class Criteria {
296 .add("id", vlanId).toString(); 415 .add("id", vlanId).toString();
297 } 416 }
298 417
418 + @Override
419 + public int hashCode() {
420 + return Objects.hash(vlanId);
421 + }
422 +
423 + @Override
424 + public boolean equals(Object obj) {
425 + if (this == obj) {
426 + return true;
427 + }
428 + if (obj instanceof VlanIdCriterion) {
429 + VlanIdCriterion that = (VlanIdCriterion) obj;
430 + return Objects.equals(vlanId, that.vlanId);
431 +
432 +
433 + }
434 + return false;
435 + }
436 +
299 } 437 }
300 438
301 439
......
...@@ -5,6 +5,9 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,6 +5,9 @@ import static org.slf4j.LoggerFactory.getLogger;
5 5
6 import java.util.Iterator; 6 import java.util.Iterator;
7 import java.util.List; 7 import java.util.List;
8 +import java.util.Map;
9 +import java.util.concurrent.ConcurrentHashMap;
10 +import java.util.concurrent.atomic.AtomicInteger;
8 11
9 import org.apache.felix.scr.annotations.Activate; 12 import org.apache.felix.scr.annotations.Activate;
10 import org.apache.felix.scr.annotations.Component; 13 import org.apache.felix.scr.annotations.Component;
...@@ -59,6 +62,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -59,6 +62,8 @@ implements FlowRuleService, FlowRuleProviderRegistry {
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 62 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 protected DeviceService deviceService; 63 protected DeviceService deviceService;
61 64
65 + private final Map<FlowRule, AtomicInteger> deadRounds = new ConcurrentHashMap<>();
66 +
62 @Activate 67 @Activate
63 public void activate() { 68 public void activate() {
64 store.setDelegate(delegate); 69 store.setDelegate(delegate);
...@@ -84,6 +89,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -84,6 +89,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
84 FlowRule f = flowRules[i]; 89 FlowRule f = flowRules[i];
85 final Device device = deviceService.getDevice(f.deviceId()); 90 final Device device = deviceService.getDevice(f.deviceId());
86 final FlowRuleProvider frp = getProvider(device.providerId()); 91 final FlowRuleProvider frp = getProvider(device.providerId());
92 + deadRounds.put(f, new AtomicInteger(0));
87 store.storeFlowRule(f); 93 store.storeFlowRule(f);
88 frp.applyFlowRule(f); 94 frp.applyFlowRule(f);
89 } 95 }
...@@ -98,6 +104,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -98,6 +104,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
98 f = flowRules[i]; 104 f = flowRules[i];
99 device = deviceService.getDevice(f.deviceId()); 105 device = deviceService.getDevice(f.deviceId());
100 frp = getProvider(device.providerId()); 106 frp = getProvider(device.providerId());
107 + deadRounds.remove(f);
101 store.deleteFlowRule(f); 108 store.deleteFlowRule(f);
102 frp.removeFlowRule(f); 109 frp.removeFlowRule(f);
103 } 110 }
...@@ -161,11 +168,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -161,11 +168,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
161 switch (stored.state()) { 168 switch (stored.state()) {
162 case ADDED: 169 case ADDED:
163 case PENDING_ADD: 170 case PENDING_ADD:
164 - if (flowRule.expired()) {
165 - event = store.removeFlowRule(flowRule);
166 - } else {
167 frp.applyFlowRule(stored); 171 frp.applyFlowRule(stored);
168 - }
169 break; 172 break;
170 case PENDING_REMOVE: 173 case PENDING_REMOVE:
171 case REMOVED: 174 case REMOVED:
...@@ -181,8 +184,8 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -181,8 +184,8 @@ implements FlowRuleService, FlowRuleProviderRegistry {
181 } 184 }
182 } 185 }
183 186
184 - @Override 187 +
185 - public void flowMissing(FlowRule flowRule) { 188 + private void flowMissing(FlowRule flowRule) {
186 checkNotNull(flowRule, FLOW_RULE_NULL); 189 checkNotNull(flowRule, FLOW_RULE_NULL);
187 checkValidity(); 190 checkValidity();
188 Device device = deviceService.getDevice(flowRule.deviceId()); 191 Device device = deviceService.getDevice(flowRule.deviceId());
...@@ -209,19 +212,22 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -209,19 +212,22 @@ implements FlowRuleService, FlowRuleProviderRegistry {
209 212
210 } 213 }
211 214
212 - @Override 215 +
213 - public void extraneousFlow(FlowRule flowRule) { 216 + private void extraneousFlow(FlowRule flowRule) {
214 checkNotNull(flowRule, FLOW_RULE_NULL); 217 checkNotNull(flowRule, FLOW_RULE_NULL);
215 checkValidity(); 218 checkValidity();
216 removeFlowRules(flowRule); 219 removeFlowRules(flowRule);
217 log.debug("Flow {} is on switch but not in store.", flowRule); 220 log.debug("Flow {} is on switch but not in store.", flowRule);
218 } 221 }
219 222
220 - @Override 223 +
221 - public void flowAdded(FlowRule flowRule) { 224 + private void flowAdded(FlowRule flowRule) {
222 checkNotNull(flowRule, FLOW_RULE_NULL); 225 checkNotNull(flowRule, FLOW_RULE_NULL);
223 checkValidity(); 226 checkValidity();
224 227
228 + if (deadRounds.containsKey(flowRule) &&
229 + checkRuleLiveness(flowRule, store.getFlowRule(flowRule))) {
230 +
225 FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule); 231 FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule);
226 if (event == null) { 232 if (event == null) {
227 log.debug("No flow store event generated."); 233 log.debug("No flow store event generated.");
...@@ -229,6 +235,21 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -229,6 +235,21 @@ implements FlowRuleService, FlowRuleProviderRegistry {
229 log.debug("Flow {} {}", flowRule, event.type()); 235 log.debug("Flow {} {}", flowRule, event.type());
230 post(event); 236 post(event);
231 } 237 }
238 + } else {
239 + removeFlowRules(flowRule);
240 + }
241 +
242 + }
243 +
244 + private boolean checkRuleLiveness(FlowRule swRule, FlowRule storedRule) {
245 + int timeout = storedRule.timeout();
246 + if (storedRule.packets() != swRule.packets()) {
247 + deadRounds.get(swRule).set(0);
248 + return true;
249 + }
250 +
251 + return (deadRounds.get(swRule).getAndIncrement() *
252 + FlowRuleProvider.POLL_INTERVAL) <= timeout;
232 253
233 } 254 }
234 255
......
...@@ -9,7 +9,9 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; ...@@ -9,7 +9,9 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
9 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED; 9 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
10 10
11 import java.util.ArrayList; 11 import java.util.ArrayList;
12 +import java.util.Collections;
12 import java.util.List; 13 import java.util.List;
14 +import java.util.Set;
13 15
14 import org.junit.After; 16 import org.junit.After;
15 import org.junit.Before; 17 import org.junit.Before;
...@@ -42,6 +44,7 @@ import org.onlab.onos.net.provider.AbstractProvider; ...@@ -42,6 +44,7 @@ import org.onlab.onos.net.provider.AbstractProvider;
42 import org.onlab.onos.net.provider.ProviderId; 44 import org.onlab.onos.net.provider.ProviderId;
43 import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore; 45 import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore;
44 46
47 +import com.google.common.collect.ImmutableList;
45 import com.google.common.collect.Lists; 48 import com.google.common.collect.Lists;
46 import com.google.common.collect.Sets; 49 import com.google.common.collect.Sets;
47 50
...@@ -52,6 +55,7 @@ public class FlowRuleManagerTest { ...@@ -52,6 +55,7 @@ public class FlowRuleManagerTest {
52 55
53 private static final ProviderId PID = new ProviderId("of", "foo"); 56 private static final ProviderId PID = new ProviderId("of", "foo");
54 private static final DeviceId DID = DeviceId.deviceId("of:001"); 57 private static final DeviceId DID = DeviceId.deviceId("of:001");
58 + private static final int TIMEOUT = 10;
55 private static final Device DEV = new DefaultDevice( 59 private static final Device DEV = new DefaultDevice(
56 PID, DID, Type.SWITCH, "", "", "", ""); 60 PID, DID, Type.SWITCH, "", "", "", "");
57 61
...@@ -96,7 +100,7 @@ public class FlowRuleManagerTest { ...@@ -96,7 +100,7 @@ public class FlowRuleManagerTest {
96 private FlowRule flowRule(int tsval, int trval) { 100 private FlowRule flowRule(int tsval, int trval) {
97 TestSelector ts = new TestSelector(tsval); 101 TestSelector ts = new TestSelector(tsval);
98 TestTreatment tr = new TestTreatment(trval); 102 TestTreatment tr = new TestTreatment(trval);
99 - return new DefaultFlowRule(DID, ts, tr, 0, appId); 103 + return new DefaultFlowRule(DID, ts, tr, 0, appId, TIMEOUT);
100 } 104 }
101 105
102 private FlowRule flowRule(FlowRule rule, FlowRuleState state) { 106 private FlowRule flowRule(FlowRule rule, FlowRuleState state) {
...@@ -105,7 +109,8 @@ public class FlowRuleManagerTest { ...@@ -105,7 +109,8 @@ public class FlowRuleManagerTest {
105 109
106 private FlowRule addFlowRule(int hval) { 110 private FlowRule addFlowRule(int hval) {
107 FlowRule rule = flowRule(hval, hval); 111 FlowRule rule = flowRule(hval, hval);
108 - providerService.flowAdded(rule); 112 + service.applyFlowRules(rule);
113 +
109 assertNotNull("rule should be found", service.getFlowEntries(DID)); 114 assertNotNull("rule should be found", service.getFlowEntries(DID));
110 return rule; 115 return rule;
111 } 116 }
...@@ -135,13 +140,18 @@ public class FlowRuleManagerTest { ...@@ -135,13 +140,18 @@ public class FlowRuleManagerTest {
135 public void getFlowEntries() { 140 public void getFlowEntries() {
136 assertTrue("store should be empty", 141 assertTrue("store should be empty",
137 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty()); 142 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
138 - addFlowRule(1); 143 + FlowRule f1 = addFlowRule(1);
139 - addFlowRule(2); 144 + FlowRule f2 = addFlowRule(2);
145 +
140 assertEquals("2 rules should exist", 2, flowCount()); 146 assertEquals("2 rules should exist", 2, flowCount());
147 +
148 + providerService.pushFlowMetrics(DID, ImmutableList.of(f1, f2));
141 validateEvents(RULE_ADDED, RULE_ADDED); 149 validateEvents(RULE_ADDED, RULE_ADDED);
142 150
143 addFlowRule(1); 151 addFlowRule(1);
144 assertEquals("should still be 2 rules", 2, flowCount()); 152 assertEquals("should still be 2 rules", 2, flowCount());
153 +
154 + providerService.pushFlowMetrics(DID, ImmutableList.of(f1));
145 validateEvents(RULE_UPDATED); 155 validateEvents(RULE_UPDATED);
146 } 156 }
147 157
...@@ -179,8 +189,10 @@ public class FlowRuleManagerTest { ...@@ -179,8 +189,10 @@ public class FlowRuleManagerTest {
179 public void removeFlowRules() { 189 public void removeFlowRules() {
180 FlowRule f1 = addFlowRule(1); 190 FlowRule f1 = addFlowRule(1);
181 FlowRule f2 = addFlowRule(2); 191 FlowRule f2 = addFlowRule(2);
182 - addFlowRule(3); 192 + FlowRule f3 = addFlowRule(3);
183 assertEquals("3 rules should exist", 3, flowCount()); 193 assertEquals("3 rules should exist", 3, flowCount());
194 +
195 + providerService.pushFlowMetrics(DID, ImmutableList.of(f1, f2, f3));
184 validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED); 196 validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED);
185 197
186 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED); 198 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
...@@ -200,8 +212,9 @@ public class FlowRuleManagerTest { ...@@ -200,8 +212,9 @@ public class FlowRuleManagerTest {
200 @Test 212 @Test
201 public void flowRemoved() { 213 public void flowRemoved() {
202 FlowRule f1 = addFlowRule(1); 214 FlowRule f1 = addFlowRule(1);
215 + FlowRule f2 = addFlowRule(2);
216 + providerService.pushFlowMetrics(f1.deviceId(), ImmutableList.of(f1, f2));
203 service.removeFlowRules(f1); 217 service.removeFlowRules(f1);
204 - addFlowRule(2);
205 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED); 218 FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
206 providerService.flowRemoved(rem1); 219 providerService.flowRemoved(rem1);
207 validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED); 220 validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
...@@ -209,9 +222,11 @@ public class FlowRuleManagerTest { ...@@ -209,9 +222,11 @@ public class FlowRuleManagerTest {
209 providerService.flowRemoved(rem1); 222 providerService.flowRemoved(rem1);
210 validateEvents(); 223 validateEvents();
211 224
212 - FlowRule f3 = flowRule(flowRule(3, 3), FlowRuleState.ADDED); 225 + FlowRule f3 = flowRule(3, 3);
213 - providerService.flowAdded(f3); 226 + service.applyFlowRules(f3);
227 + providerService.pushFlowMetrics(f3.deviceId(), Collections.singletonList(f3));
214 validateEvents(RULE_ADDED); 228 validateEvents(RULE_ADDED);
229 +
215 providerService.flowRemoved(f3); 230 providerService.flowRemoved(f3);
216 validateEvents(); 231 validateEvents();
217 } 232 }
...@@ -223,9 +238,10 @@ public class FlowRuleManagerTest { ...@@ -223,9 +238,10 @@ public class FlowRuleManagerTest {
223 FlowRule f3 = flowRule(3, 3); 238 FlowRule f3 = flowRule(3, 3);
224 239
225 240
241 +
242 + mgr.applyFlowRules(f1, f2, f3);
226 FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED); 243 FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
227 FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED); 244 FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
228 - mgr.applyFlowRules(f1, f2, f3);
229 245
230 providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2)); 246 providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2));
231 247
...@@ -233,7 +249,7 @@ public class FlowRuleManagerTest { ...@@ -233,7 +249,7 @@ public class FlowRuleManagerTest {
233 validateState(FlowRuleState.PENDING_ADD, FlowRuleState.ADDED, 249 validateState(FlowRuleState.PENDING_ADD, FlowRuleState.ADDED,
234 FlowRuleState.ADDED)); 250 FlowRuleState.ADDED));
235 251
236 - validateEvents(RULE_UPDATED, RULE_UPDATED); 252 + validateEvents(RULE_ADDED, RULE_ADDED);
237 } 253 }
238 254
239 @Test 255 @Test
...@@ -241,15 +257,15 @@ public class FlowRuleManagerTest { ...@@ -241,15 +257,15 @@ public class FlowRuleManagerTest {
241 FlowRule f1 = flowRule(1, 1); 257 FlowRule f1 = flowRule(1, 1);
242 FlowRule f2 = flowRule(2, 2); 258 FlowRule f2 = flowRule(2, 2);
243 FlowRule f3 = flowRule(3, 3); 259 FlowRule f3 = flowRule(3, 3);
260 + mgr.applyFlowRules(f1, f2);
244 261
245 FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED); 262 FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
246 FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED); 263 FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
247 FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED); 264 FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
248 - mgr.applyFlowRules(f1, f2);
249 265
250 providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2, updatedF3)); 266 providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2, updatedF3));
251 267
252 - validateEvents(RULE_UPDATED, RULE_UPDATED); 268 + validateEvents(RULE_ADDED, RULE_ADDED);
253 269
254 } 270 }
255 271
...@@ -271,7 +287,7 @@ public class FlowRuleManagerTest { ...@@ -271,7 +287,7 @@ public class FlowRuleManagerTest {
271 287
272 providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2)); 288 providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2));
273 289
274 - validateEvents(RULE_UPDATED, RULE_UPDATED, RULE_REMOVED); 290 + validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
275 291
276 } 292 }
277 293
...@@ -386,7 +402,7 @@ public class FlowRuleManagerTest { ...@@ -386,7 +402,7 @@ public class FlowRuleManagerTest {
386 } 402 }
387 403
388 @Override 404 @Override
389 - public List<Criterion> criteria() { 405 + public Set<Criterion> criteria() {
390 return null; 406 return null;
391 } 407 }
392 408
......
1 package org.onlab.onos.store.trivial.impl; 1 package org.onlab.onos.store.trivial.impl;
2 2
3 -import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
4 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; 3 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
5 import static org.slf4j.LoggerFactory.getLogger; 4 import static org.slf4j.LoggerFactory.getLogger;
6 5
...@@ -116,18 +115,21 @@ public class SimpleFlowRuleStore ...@@ -116,18 +115,21 @@ public class SimpleFlowRuleStore
116 DeviceId did = rule.deviceId(); 115 DeviceId did = rule.deviceId();
117 116
118 // check if this new rule is an update to an existing entry 117 // check if this new rule is an update to an existing entry
119 - if (flowEntries.containsEntry(did, rule)) { 118 + FlowRule stored = getFlowRule(rule);
120 - //synchronized (flowEntries) { 119 + if (stored != null) {
121 // Multimaps support duplicates so we have to remove our rule 120 // Multimaps support duplicates so we have to remove our rule
122 // and replace it with the current version. 121 // and replace it with the current version.
123 flowEntries.remove(did, rule); 122 flowEntries.remove(did, rule);
124 flowEntries.put(did, rule); 123 flowEntries.put(did, rule);
125 - //} 124 +
125 + if (stored.state() == FlowRuleState.PENDING_ADD) {
126 + return new FlowRuleEvent(Type.RULE_ADDED, rule);
127 + }
126 return new FlowRuleEvent(Type.RULE_UPDATED, rule); 128 return new FlowRuleEvent(Type.RULE_UPDATED, rule);
127 } 129 }
128 130
129 flowEntries.put(did, rule); 131 flowEntries.put(did, rule);
130 - return new FlowRuleEvent(RULE_ADDED, rule); 132 + return null;
131 } 133 }
132 134
133 @Override 135 @Override
...@@ -140,11 +142,4 @@ public class SimpleFlowRuleStore ...@@ -140,11 +142,4 @@ public class SimpleFlowRuleStore
140 } 142 }
141 //} 143 //}
142 } 144 }
143 -
144 -
145 -
146 -
147 -
148 -
149 -
150 } 145 }
......
...@@ -77,7 +77,6 @@ public class FlowModBuilder { ...@@ -77,7 +77,6 @@ public class FlowModBuilder {
77 .setCookie(U64.of(cookie.value())) 77 .setCookie(U64.of(cookie.value()))
78 .setBufferId(OFBufferId.NO_BUFFER) 78 .setBufferId(OFBufferId.NO_BUFFER)
79 .setActions(actions) 79 .setActions(actions)
80 - .setIdleTimeout(10)
81 .setMatch(match) 80 .setMatch(match)
82 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 81 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
83 .setPriority(priority) 82 .setPriority(priority)
......
...@@ -71,7 +71,7 @@ public class FlowRuleBuilder { ...@@ -71,7 +71,7 @@ public class FlowRuleBuilder {
71 buildSelector(), buildTreatment(), stat.getPriority(), 71 buildSelector(), buildTreatment(), stat.getPriority(),
72 FlowRuleState.ADDED, stat.getDurationNsec() / 1000000, 72 FlowRuleState.ADDED, stat.getDurationNsec() / 1000000,
73 stat.getPacketCount().getValue(), stat.getByteCount().getValue(), 73 stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
74 - stat.getCookie().getValue(), false); 74 + stat.getCookie().getValue(), false, stat.getIdleTimeout());
75 } else { 75 } else {
76 // TODO: revisit potentially. 76 // TODO: revisit potentially.
77 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), 77 return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
...@@ -79,7 +79,8 @@ public class FlowRuleBuilder { ...@@ -79,7 +79,8 @@ public class FlowRuleBuilder {
79 FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000, 79 FlowRuleState.REMOVED, removed.getDurationNsec() / 1000000,
80 removed.getPacketCount().getValue(), removed.getByteCount().getValue(), 80 removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
81 removed.getCookie().getValue(), 81 removed.getCookie().getValue(),
82 - removed.getReason() == OFFlowRemovedReason.IDLE_TIMEOUT.ordinal()); 82 + removed.getReason() == OFFlowRemovedReason.IDLE_TIMEOUT.ordinal(),
83 + stat.getIdleTimeout());
83 } 84 }
84 } 85 }
85 86
......
...@@ -127,7 +127,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr ...@@ -127,7 +127,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
127 127
128 @Override 128 @Override
129 public void switchAdded(Dpid dpid) { 129 public void switchAdded(Dpid dpid) {
130 - FlowStatsCollector fsc = new FlowStatsCollector(controller.getSwitch(dpid), 5); 130 + FlowStatsCollector fsc = new FlowStatsCollector(controller.getSwitch(dpid), POLL_INTERVAL);
131 fsc.start(); 131 fsc.start();
132 collectors.put(dpid, fsc); 132 collectors.put(dpid, fsc);
133 } 133 }
......
...@@ -176,7 +176,7 @@ ...@@ -176,7 +176,7 @@
176 </module> 176 </module>
177 177
178 <module name="ParameterNumber"> 178 <module name="ParameterNumber">
179 - <property name="max" value="10"/> 179 + <property name="max" value="15"/>
180 <property name="tokens" value="CTOR_DEF"/> 180 <property name="tokens" value="CTOR_DEF"/>
181 </module> 181 </module>
182 <!-- Checks for whitespace --> 182 <!-- Checks for whitespace -->
......