Murat Parlakisik
Committed by Gerrit Code Review

ONOS-4374 Enable installing flows with hard_timeout

Change-Id: I4e60e93aad44c7e8f8913fa4dd3ed5a2565d7034
...@@ -46,6 +46,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -46,6 +46,8 @@ public class DefaultFlowRule implements FlowRule {
46 46
47 private final int timeout; 47 private final int timeout;
48 private final boolean permanent; 48 private final boolean permanent;
49 + private final int hardTimeout;
50 + private final FlowRemoveReason reason;
49 private final GroupId groupId; 51 private final GroupId groupId;
50 52
51 private final Integer tableId; 53 private final Integer tableId;
...@@ -60,6 +62,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -60,6 +62,8 @@ public class DefaultFlowRule implements FlowRule {
60 this.groupId = rule.groupId(); 62 this.groupId = rule.groupId();
61 this.id = rule.id(); 63 this.id = rule.id();
62 this.timeout = rule.timeout(); 64 this.timeout = rule.timeout();
65 + this.hardTimeout = rule.hardTimeout();
66 + this.reason = rule.reason();
63 this.permanent = rule.isPermanent(); 67 this.permanent = rule.isPermanent();
64 this.created = System.currentTimeMillis(); 68 this.created = System.currentTimeMillis();
65 this.tableId = rule.tableId(); 69 this.tableId = rule.tableId();
...@@ -68,8 +72,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -68,8 +72,8 @@ public class DefaultFlowRule implements FlowRule {
68 72
69 private DefaultFlowRule(DeviceId deviceId, TrafficSelector selector, 73 private DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
70 TrafficTreatment treatment, Integer priority, 74 TrafficTreatment treatment, Integer priority,
71 - FlowId flowId, Boolean permanent, Integer timeout, 75 + FlowId flowId, Boolean permanent, Integer timeout, Integer hardTimeout,
72 - Integer tableId) { 76 + FlowRemoveReason reason, Integer tableId) {
73 77
74 this.deviceId = deviceId; 78 this.deviceId = deviceId;
75 this.selector = selector; 79 this.selector = selector;
...@@ -79,6 +83,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -79,6 +83,8 @@ public class DefaultFlowRule implements FlowRule {
79 this.id = flowId; 83 this.id = flowId;
80 this.permanent = permanent; 84 this.permanent = permanent;
81 this.timeout = timeout; 85 this.timeout = timeout;
86 + this.hardTimeout = hardTimeout;
87 + this.reason = reason;
82 this.tableId = tableId; 88 this.tableId = tableId;
83 this.created = System.currentTimeMillis(); 89 this.created = System.currentTimeMillis();
84 90
...@@ -88,6 +94,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -88,6 +94,8 @@ public class DefaultFlowRule implements FlowRule {
88 this.payLoad = null; 94 this.payLoad = null;
89 } 95 }
90 96
97 +
98 +
91 /** 99 /**
92 * Support for the third party flow rule. Creates a flow rule of flow table. 100 * Support for the third party flow rule. Creates a flow rule of flow table.
93 * 101 *
...@@ -105,6 +113,28 @@ public class DefaultFlowRule implements FlowRule { ...@@ -105,6 +113,28 @@ public class DefaultFlowRule implements FlowRule {
105 TrafficTreatment treatment, int priority, 113 TrafficTreatment treatment, int priority,
106 ApplicationId appId, int timeout, boolean permanent, 114 ApplicationId appId, int timeout, boolean permanent,
107 FlowRuleExtPayLoad payLoad) { 115 FlowRuleExtPayLoad payLoad) {
116 + this(deviceId, selector, treatment, priority, appId, timeout, 0, permanent, payLoad);
117 + }
118 +
119 +
120 + /**
121 + * Support for the third party flow rule. Creates a flow rule of flow table.
122 + *
123 + * @param deviceId the identity of the device where this rule applies
124 + * @param selector the traffic selector that identifies what traffic this
125 + * rule
126 + * @param treatment the traffic treatment that applies to selected traffic
127 + * @param priority the flow rule priority given in natural order
128 + * @param appId the application id of this flow
129 + * @param timeout the timeout for this flow requested by an application
130 + * @param hardTimeout the hard timeout located switch's flow table for this flow requested by an application
131 + * @param permanent whether the flow is permanent i.e. does not time out
132 + * @param payLoad 3rd-party origin private flow
133 + */
134 + public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
135 + TrafficTreatment treatment, int priority,
136 + ApplicationId appId, int timeout, int hardTimeout, boolean permanent,
137 + FlowRuleExtPayLoad payLoad) {
108 138
109 checkArgument(priority >= MIN_PRIORITY, "Priority cannot be less than " + 139 checkArgument(priority >= MIN_PRIORITY, "Priority cannot be less than " +
110 MIN_PRIORITY); 140 MIN_PRIORITY);
...@@ -118,6 +148,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -118,6 +148,8 @@ public class DefaultFlowRule implements FlowRule {
118 this.appId = appId.id(); 148 this.appId = appId.id();
119 this.groupId = new DefaultGroupId(0); 149 this.groupId = new DefaultGroupId(0);
120 this.timeout = timeout; 150 this.timeout = timeout;
151 + this.reason = FlowRemoveReason.NO_REASON;
152 + this.hardTimeout = hardTimeout;
121 this.permanent = permanent; 153 this.permanent = permanent;
122 this.tableId = 0; 154 this.tableId = 0;
123 this.created = System.currentTimeMillis(); 155 this.created = System.currentTimeMillis();
...@@ -152,6 +184,30 @@ public class DefaultFlowRule implements FlowRule { ...@@ -152,6 +184,30 @@ public class DefaultFlowRule implements FlowRule {
152 TrafficTreatment treatment, int priority, 184 TrafficTreatment treatment, int priority,
153 ApplicationId appId, GroupId groupId, int timeout, 185 ApplicationId appId, GroupId groupId, int timeout,
154 boolean permanent, FlowRuleExtPayLoad payLoad) { 186 boolean permanent, FlowRuleExtPayLoad payLoad) {
187 + this(deviceId, selector, treatment, priority, appId, groupId, timeout, 0, permanent, payLoad);
188 + }
189 +
190 + /**
191 + * Support for the third party flow rule. Creates a flow rule of group
192 + * table.
193 + *
194 + * @param deviceId the identity of the device where this rule applies
195 + * @param selector the traffic selector that identifies what traffic this
196 + * rule
197 + * @param treatment the traffic treatment that applies to selected traffic
198 + * @param priority the flow rule priority given in natural order
199 + * @param appId the application id of this flow
200 + * @param groupId the group id of this flow
201 + * @param timeout the timeout for this flow requested by an application
202 + * @param hardTimeout the hard timeout located switch's flow table for this flow requested by an application
203 + * @param permanent whether the flow is permanent i.e. does not time out
204 + * @param payLoad 3rd-party origin private flow
205 + *
206 + */
207 + public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
208 + TrafficTreatment treatment, int priority,
209 + ApplicationId appId, GroupId groupId, int timeout, int hardTimeout,
210 + boolean permanent, FlowRuleExtPayLoad payLoad) {
155 211
156 checkArgument(priority >= MIN_PRIORITY, "Priority cannot be less than " + 212 checkArgument(priority >= MIN_PRIORITY, "Priority cannot be less than " +
157 MIN_PRIORITY); 213 MIN_PRIORITY);
...@@ -165,6 +221,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -165,6 +221,8 @@ public class DefaultFlowRule implements FlowRule {
165 this.appId = appId.id(); 221 this.appId = appId.id();
166 this.groupId = groupId; 222 this.groupId = groupId;
167 this.timeout = timeout; 223 this.timeout = timeout;
224 + this.reason = FlowRemoveReason.NO_REASON;
225 + this.hardTimeout = hardTimeout;
168 this.permanent = permanent; 226 this.permanent = permanent;
169 this.created = System.currentTimeMillis(); 227 this.created = System.currentTimeMillis();
170 this.tableId = 0; 228 this.tableId = 0;
...@@ -280,6 +338,18 @@ public class DefaultFlowRule implements FlowRule { ...@@ -280,6 +338,18 @@ public class DefaultFlowRule implements FlowRule {
280 return timeout; 338 return timeout;
281 } 339 }
282 340
341 +
342 +
343 + @Override
344 + public int hardTimeout() {
345 + return hardTimeout;
346 + }
347 +
348 + @Override
349 + public FlowRemoveReason reason() {
350 + return reason;
351 + }
352 +
283 @Override 353 @Override
284 public boolean isPermanent() { 354 public boolean isPermanent() {
285 return permanent; 355 return permanent;
...@@ -310,6 +380,8 @@ public class DefaultFlowRule implements FlowRule { ...@@ -310,6 +380,8 @@ public class DefaultFlowRule implements FlowRule {
310 private TrafficTreatment treatment = DefaultTrafficTreatment.builder().build(); 380 private TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
311 private Integer timeout; 381 private Integer timeout;
312 private Boolean permanent; 382 private Boolean permanent;
383 + private Integer hardTimeout = 0;
384 + private FlowRemoveReason reason = FlowRemoveReason.NO_REASON;
313 385
314 @Override 386 @Override
315 public FlowRule.Builder withCookie(long cookie) { 387 public FlowRule.Builder withCookie(long cookie) {
...@@ -368,6 +440,20 @@ public class DefaultFlowRule implements FlowRule { ...@@ -368,6 +440,20 @@ public class DefaultFlowRule implements FlowRule {
368 } 440 }
369 441
370 @Override 442 @Override
443 + public FlowRule.Builder withHardTimeout(int timeout) {
444 + this.permanent = false;
445 + this.hardTimeout = timeout;
446 + this.timeout = timeout;
447 + return this;
448 + }
449 +
450 + @Override
451 + public FlowRule.Builder withReason(FlowRemoveReason reason) {
452 + this.reason = reason;
453 + return this;
454 + }
455 +
456 + @Override
371 public FlowRule build() { 457 public FlowRule build() {
372 FlowId localFlowId; 458 FlowId localFlowId;
373 checkArgument((flowId != null) ^ (appId != null), "Either an application" + 459 checkArgument((flowId != null) ^ (appId != null), "Either an application" +
...@@ -390,7 +476,7 @@ public class DefaultFlowRule implements FlowRule { ...@@ -390,7 +476,7 @@ public class DefaultFlowRule implements FlowRule {
390 } 476 }
391 477
392 return new DefaultFlowRule(deviceId, selector, treatment, priority, 478 return new DefaultFlowRule(deviceId, selector, treatment, priority,
393 - localFlowId, permanent, timeout, tableId); 479 + localFlowId, permanent, timeout, hardTimeout, reason, tableId);
394 } 480 }
395 481
396 private FlowId computeFlowId(ApplicationId appId) { 482 private FlowId computeFlowId(ApplicationId appId) {
......
...@@ -30,6 +30,28 @@ public interface FlowRule { ...@@ -30,6 +30,28 @@ public interface FlowRule {
30 int MAX_PRIORITY = 65535; 30 int MAX_PRIORITY = 65535;
31 31
32 /** 32 /**
33 + * Reason for flow parameter received from switches.
34 + * Used to check reason parameter in flows.
35 + */
36 + enum FlowRemoveReason {
37 + NO_REASON,
38 + IDLE_TIMEOUT,
39 + HARD_TIMEOUT;
40 + public static FlowRemoveReason parseShort(short reason) {
41 + switch (reason) {
42 + case -1 :
43 + return NO_REASON;
44 + case 0:
45 + return IDLE_TIMEOUT;
46 + case 1:
47 + return HARD_TIMEOUT;
48 + default :
49 + return NO_REASON;
50 + }
51 + }
52 + }
53 +
54 + /**
33 * Returns the ID of this flow. 55 * Returns the ID of this flow.
34 * 56 *
35 * @return the flow ID 57 * @return the flow ID
...@@ -88,6 +110,21 @@ public interface FlowRule { ...@@ -88,6 +110,21 @@ public interface FlowRule {
88 int timeout(); 110 int timeout();
89 111
90 /** 112 /**
113 + * Returns the hard timeout for this flow requested by an application.
114 + * This paremeter configure switch's flow hard timeout.
115 + * In case of controller-switch connection lost, this variable can be useful.
116 + * @return integer value of the hard Timeout
117 + */
118 + int hardTimeout();
119 +
120 + /**
121 + * Returns the reason for the flow received from switches.
122 + *
123 + * @return FlowRemoveReason value of reason
124 + */
125 + FlowRemoveReason reason();
126 +
127 + /**
91 * Returns whether the flow is permanent i.e. does not time out. 128 * Returns whether the flow is permanent i.e. does not time out.
92 * 129 *
93 * @return true if the flow is permanent, otherwise false 130 * @return true if the flow is permanent, otherwise false
...@@ -212,6 +249,20 @@ public interface FlowRule { ...@@ -212,6 +249,20 @@ public interface FlowRule {
212 Builder makeTemporary(int timeout); 249 Builder makeTemporary(int timeout);
213 250
214 /** 251 /**
252 + * Sets hard timeout parameter in flow table.
253 + * @param timeout an integer
254 + * @return this
255 + */
256 + Builder withHardTimeout(int timeout);
257 +
258 + /**
259 + * Sets reason parameter received from switches .
260 + * @param reason a short
261 + * @return this
262 + */
263 + Builder withReason(FlowRemoveReason reason);
264 +
265 + /**
215 * Builds a flow rule object. 266 * Builds a flow rule object.
216 * 267 *
217 * @return a flow rule. 268 * @return a flow rule.
......
...@@ -26,6 +26,7 @@ import org.onosproject.net.Link; ...@@ -26,6 +26,7 @@ import org.onosproject.net.Link;
26 import org.onosproject.net.NetTestTools; 26 import org.onosproject.net.NetTestTools;
27 import org.onosproject.net.NetworkResource; 27 import org.onosproject.net.NetworkResource;
28 import org.onosproject.net.Path; 28 import org.onosproject.net.Path;
29 +import org.onosproject.net.flow.FlowRule.FlowRemoveReason;
29 import org.onosproject.net.flow.FlowId; 30 import org.onosproject.net.flow.FlowId;
30 import org.onosproject.net.flow.FlowRule; 31 import org.onosproject.net.flow.FlowRule;
31 import org.onosproject.net.flow.FlowRuleExtPayLoad; 32 import org.onosproject.net.flow.FlowRuleExtPayLoad;
...@@ -330,6 +331,16 @@ public class IntentTestsMocks { ...@@ -330,6 +331,16 @@ public class IntentTestsMocks {
330 } 331 }
331 332
332 @Override 333 @Override
334 + public int hardTimeout() {
335 + return 0;
336 + }
337 +
338 + @Override
339 + public FlowRemoveReason reason() {
340 + return FlowRemoveReason.NO_REASON;
341 + }
342 +
343 + @Override
333 public boolean isPermanent() { 344 public boolean isPermanent() {
334 return false; 345 return false;
335 } 346 }
......
...@@ -313,8 +313,10 @@ public class FlowRuleManager ...@@ -313,8 +313,10 @@ public class FlowRuleManager
313 extends AbstractProviderService<FlowRuleProvider> 313 extends AbstractProviderService<FlowRuleProvider>
314 implements FlowRuleProviderService { 314 implements FlowRuleProviderService {
315 315
316 + final Map<FlowEntry, Long> firstSeen = Maps.newConcurrentMap();
316 final Map<FlowEntry, Long> lastSeen = Maps.newConcurrentMap(); 317 final Map<FlowEntry, Long> lastSeen = Maps.newConcurrentMap();
317 318
319 +
318 protected InternalFlowRuleProviderService(FlowRuleProvider provider) { 320 protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
319 super(provider); 321 super(provider);
320 } 322 }
...@@ -324,11 +326,15 @@ public class FlowRuleManager ...@@ -324,11 +326,15 @@ public class FlowRuleManager
324 checkNotNull(flowEntry, FLOW_RULE_NULL); 326 checkNotNull(flowEntry, FLOW_RULE_NULL);
325 checkValidity(); 327 checkValidity();
326 lastSeen.remove(flowEntry); 328 lastSeen.remove(flowEntry);
329 + firstSeen.remove(flowEntry);
327 FlowEntry stored = store.getFlowEntry(flowEntry); 330 FlowEntry stored = store.getFlowEntry(flowEntry);
328 if (stored == null) { 331 if (stored == null) {
329 log.debug("Rule already evicted from store: {}", flowEntry); 332 log.debug("Rule already evicted from store: {}", flowEntry);
330 return; 333 return;
331 } 334 }
335 + if (flowEntry.reason() == FlowEntry.FlowRemoveReason.HARD_TIMEOUT) {
336 + ((DefaultFlowEntry) stored).setState(FlowEntry.FlowEntryState.REMOVED);
337 + }
332 Device device = deviceService.getDevice(flowEntry.deviceId()); 338 Device device = deviceService.getDevice(flowEntry.deviceId());
333 FlowRuleProvider frp = getProvider(device.providerId()); 339 FlowRuleProvider frp = getProvider(device.providerId());
334 FlowRuleEvent event = null; 340 FlowRuleEvent event = null;
...@@ -422,6 +428,21 @@ public class FlowRuleManager ...@@ -422,6 +428,21 @@ public class FlowRuleManager
422 428
423 final long timeout = storedRule.timeout() * 1000; 429 final long timeout = storedRule.timeout() * 1000;
424 final long currentTime = System.currentTimeMillis(); 430 final long currentTime = System.currentTimeMillis();
431 +
432 + // Checking flow with hardTimeout
433 + if (storedRule.hardTimeout() != 0) {
434 + if (!firstSeen.containsKey(storedRule)) {
435 + // First time rule adding
436 + firstSeen.put(storedRule, currentTime);
437 + } else {
438 + Long first = firstSeen.get(storedRule);
439 + final long hardTimeout = storedRule.hardTimeout() * 1000;
440 + if ((currentTime - first) > hardTimeout) {
441 + return false;
442 + }
443 + }
444 + }
445 +
425 if (storedRule.packets() != swRule.packets()) { 446 if (storedRule.packets() != swRule.packets()) {
426 lastSeen.put(storedRule, currentTime); 447 lastSeen.put(storedRule, currentTime);
427 return true; 448 return true;
......
...@@ -101,6 +101,7 @@ import org.onosproject.net.flow.DefaultTrafficSelector; ...@@ -101,6 +101,7 @@ import org.onosproject.net.flow.DefaultTrafficSelector;
101 import org.onosproject.net.flow.DefaultTrafficTreatment; 101 import org.onosproject.net.flow.DefaultTrafficTreatment;
102 import org.onosproject.net.flow.FlowEntry; 102 import org.onosproject.net.flow.FlowEntry;
103 import org.onosproject.net.flow.FlowId; 103 import org.onosproject.net.flow.FlowId;
104 +import org.onosproject.net.flow.FlowRule;
104 import org.onosproject.net.flow.FlowRuleBatchEntry; 105 import org.onosproject.net.flow.FlowRuleBatchEntry;
105 import org.onosproject.net.flow.FlowRuleBatchEvent; 106 import org.onosproject.net.flow.FlowRuleBatchEvent;
106 import org.onosproject.net.flow.FlowRuleBatchOperation; 107 import org.onosproject.net.flow.FlowRuleBatchOperation;
...@@ -349,6 +350,7 @@ public final class KryoNamespaces { ...@@ -349,6 +350,7 @@ public final class KryoNamespaces {
349 DefaultFlowEntry.class, 350 DefaultFlowEntry.class,
350 StoredFlowEntry.class, 351 StoredFlowEntry.class,
351 DefaultFlowRule.class, 352 DefaultFlowRule.class,
353 + FlowRule.FlowRemoveReason.class,
352 DefaultPacketRequest.class, 354 DefaultPacketRequest.class,
353 PacketPriority.class, 355 PacketPriority.class,
354 FlowEntry.FlowEntryState.class, 356 FlowEntry.FlowEntryState.class,
......
...@@ -95,6 +95,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder { ...@@ -95,6 +95,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
95 .setMatch(match) 95 .setMatch(match)
96 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 96 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
97 .setPriority(flowRule().priority()) 97 .setPriority(flowRule().priority())
98 + .setHardTimeout(flowRule().hardTimeout())
98 .build(); 99 .build();
99 100
100 return fm; 101 return fm;
...@@ -115,6 +116,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder { ...@@ -115,6 +116,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
115 .setMatch(match) 116 .setMatch(match)
116 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 117 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
117 .setPriority(flowRule().priority()) 118 .setPriority(flowRule().priority())
119 + .setHardTimeout(flowRule().hardTimeout())
118 .build(); 120 .build();
119 121
120 return fm; 122 return fm;
...@@ -133,6 +135,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder { ...@@ -133,6 +135,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
133 .setMatch(match) 135 .setMatch(match)
134 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 136 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
135 .setPriority(flowRule().priority()) 137 .setPriority(flowRule().priority())
138 + .setHardTimeout(flowRule().hardTimeout())
136 .build(); 139 .build();
137 140
138 return fm; 141 return fm;
......
...@@ -158,6 +158,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -158,6 +158,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
158 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 158 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
159 .setPriority(flowRule().priority()) 159 .setPriority(flowRule().priority())
160 .setTableId(TableId.of(flowRule().tableId())) 160 .setTableId(TableId.of(flowRule().tableId()))
161 + .setHardTimeout(flowRule().hardTimeout())
161 .build(); 162 .build();
162 163
163 return fm; 164 return fm;
...@@ -201,6 +202,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -201,6 +202,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
201 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 202 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
202 .setPriority(flowRule().priority()) 203 .setPriority(flowRule().priority())
203 .setTableId(TableId.of(flowRule().tableId())) 204 .setTableId(TableId.of(flowRule().tableId()))
205 + .setHardTimeout(flowRule().hardTimeout())
204 .build(); 206 .build();
205 207
206 return fm; 208 return fm;
...@@ -220,6 +222,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -220,6 +222,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
220 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 222 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
221 .setPriority(flowRule().priority()) 223 .setPriority(flowRule().priority())
222 .setTableId(TableId.of(flowRule().tableId())) 224 .setTableId(TableId.of(flowRule().tableId()))
225 + .setHardTimeout(flowRule().hardTimeout())
223 .build(); 226 .build();
224 227
225 return fm; 228 return fm;
......
...@@ -182,7 +182,9 @@ public class FlowEntryBuilder { ...@@ -182,7 +182,9 @@ public class FlowEntryBuilder {
182 .withSelector(buildSelector()) 182 .withSelector(buildSelector())
183 .withPriority(removed.getPriority()) 183 .withPriority(removed.getPriority())
184 .makeTemporary(removed.getIdleTimeout()) 184 .makeTemporary(removed.getIdleTimeout())
185 - .withCookie(removed.getCookie().getValue()); 185 + .withCookie(removed.getCookie().getValue())
186 + .withReason(FlowRule.FlowRemoveReason.parseShort(removed.getReason()));
187 +
186 if (removed.getVersion() != OFVersion.OF_10) { 188 if (removed.getVersion() != OFVersion.OF_10) {
187 builder.forTable(removed.getTableId().getValue()); 189 builder.forTable(removed.getTableId().getValue());
188 } 190 }
......
...@@ -46,6 +46,7 @@ import org.onosproject.net.flow.DefaultTrafficSelector; ...@@ -46,6 +46,7 @@ import org.onosproject.net.flow.DefaultTrafficSelector;
46 import org.onosproject.net.flow.DefaultTrafficTreatment; 46 import org.onosproject.net.flow.DefaultTrafficTreatment;
47 import org.onosproject.net.flow.FlowEntry; 47 import org.onosproject.net.flow.FlowEntry;
48 import org.onosproject.net.flow.FlowId; 48 import org.onosproject.net.flow.FlowId;
49 +import org.onosproject.net.flow.FlowRule.FlowRemoveReason;
49 import org.onosproject.net.flow.FlowRule; 50 import org.onosproject.net.flow.FlowRule;
50 import org.onosproject.net.flow.FlowRuleExtPayLoad; 51 import org.onosproject.net.flow.FlowRuleExtPayLoad;
51 import org.onosproject.net.flow.FlowRuleService; 52 import org.onosproject.net.flow.FlowRuleService;
...@@ -218,6 +219,16 @@ public class FlowsResourceTest extends ResourceTest { ...@@ -218,6 +219,16 @@ public class FlowsResourceTest extends ResourceTest {
218 } 219 }
219 220
220 @Override 221 @Override
222 + public int hardTimeout() {
223 + return 0;
224 + }
225 +
226 + @Override
227 + public FlowRemoveReason reason() {
228 + return FlowRemoveReason.NO_REASON;
229 + }
230 +
231 + @Override
221 public boolean isPermanent() { 232 public boolean isPermanent() {
222 return false; 233 return false;
223 } 234 }
...@@ -295,6 +306,16 @@ public class FlowsResourceTest extends ResourceTest { ...@@ -295,6 +306,16 @@ public class FlowsResourceTest extends ResourceTest {
295 } 306 }
296 307
297 @Override 308 @Override
309 + public int hardTimeout() {
310 + return 0;
311 + }
312 +
313 + @Override
314 + public FlowRemoveReason reason() {
315 + return FlowRemoveReason.NO_REASON;
316 + }
317 +
318 + @Override
298 public boolean isPermanent() { 319 public boolean isPermanent() {
299 return false; 320 return false;
300 } 321 }
......