flowrules no longer install a timeout but are monitored by onos in order to be expired
Change-Id: Ibd1a5952349d7ccb27c92b4982d04574f31424c0
Showing
15 changed files
with
285 additions
and
90 deletions
... | @@ -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 | ... | ... |
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
... | @@ -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 --> | ... | ... |
-
Please register or login to post a comment