alshabib
Committed by Jonathan Hart

Traffic Treatements now support deferred, immediate, table, and clear instructions.

By default, treatments are all immediate. Treatments will be deferred if the builder
predicated by deferred(). Subsequent treatments will be deferred until immediate is called
on the builder again. Multiple calls to deferred and immediate are permitted.

Change-Id: I76b3a44f2219fc1e72a7fb41b72d7bd602be85b7
...@@ -34,6 +34,7 @@ import org.onlab.packet.VlanId; ...@@ -34,6 +34,7 @@ import org.onlab.packet.VlanId;
34 import org.onosproject.core.ApplicationId; 34 import org.onosproject.core.ApplicationId;
35 import org.onosproject.core.CoreService; 35 import org.onosproject.core.CoreService;
36 import org.onosproject.net.DeviceId; 36 import org.onosproject.net.DeviceId;
37 +import org.onosproject.net.PortNumber;
37 import org.onosproject.net.flow.DefaultFlowRule; 38 import org.onosproject.net.flow.DefaultFlowRule;
38 import org.onosproject.net.flow.DefaultTrafficSelector; 39 import org.onosproject.net.flow.DefaultTrafficSelector;
39 import org.onosproject.net.flow.DefaultTrafficTreatment; 40 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -322,7 +323,7 @@ public class BgpRouter { ...@@ -322,7 +323,7 @@ public class BgpRouter {
322 private static final int HIGHEST_PRIORITY = 0xffff; 323 private static final int HIGHEST_PRIORITY = 0xffff;
323 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>(); 324 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
324 private Set<MacAddress> intfMacs = new HashSet<MacAddress>(); 325 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
325 - private Set<VlanId> intfVlans = new HashSet<VlanId>(); 326 + private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
326 327
327 public void provision(boolean install, Set<Interface> intfs) { 328 public void provision(boolean install, Set<Interface> intfs) {
328 getIntefaceConfig(intfs); 329 getIntefaceConfig(intfs);
...@@ -341,7 +342,7 @@ public class BgpRouter { ...@@ -341,7 +342,7 @@ public class BgpRouter {
341 for (Interface intf : intfs) { 342 for (Interface intf : intfs) {
342 intfIps.addAll(intf.ipAddresses()); 343 intfIps.addAll(intf.ipAddresses());
343 intfMacs.add(intf.mac()); 344 intfMacs.add(intf.mac());
344 - intfVlans.add(intf.vlan()); 345 + portVlanPair.put(intf.connectPoint().port(), intf.vlan());
345 } 346 }
346 } 347 }
347 348
...@@ -447,14 +448,15 @@ public class BgpRouter { ...@@ -447,14 +448,15 @@ public class BgpRouter {
447 FlowRule rule; 448 FlowRule rule;
448 449
449 //Interface Vlans 450 //Interface Vlans
450 - for (VlanId vid : intfVlans) { 451 + for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
451 - log.debug("adding rule for VLAN: {}", vid); 452 + log.debug("adding rule for VLAN: {}", portVlan);
452 selector = DefaultTrafficSelector.builder(); 453 selector = DefaultTrafficSelector.builder();
453 treatment = DefaultTrafficTreatment.builder(); 454 treatment = DefaultTrafficTreatment.builder();
454 455
455 - selector.matchVlanId(vid); 456 + selector.matchVlanId(portVlan.getValue());
456 - treatment.stripVlan(); 457 + selector.matchInPort(portVlan.getKey());
457 treatment.transition(Type.ETHER); 458 treatment.transition(Type.ETHER);
459 + treatment.deferred().popVlan();
458 460
459 rule = new DefaultFlowRule(deviceId, selector.build(), 461 rule = new DefaultFlowRule(deviceId, selector.build(),
460 treatment.build(), CONTROLLER_PRIORITY, appId, 462 treatment.build(), CONTROLLER_PRIORITY, appId,
......
...@@ -195,7 +195,7 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -195,7 +195,7 @@ public class FlowsListCommand extends AbstractShellCommand {
195 f.bytes(), f.packets(), f.life(), f.priority(), f.type(), 195 f.bytes(), f.packets(), f.life(), f.priority(), f.type(),
196 coreService.getAppId(f.appId()).name()); 196 coreService.getAppId(f.appId()).name());
197 print(SFMT, f.selector().criteria()); 197 print(SFMT, f.selector().criteria());
198 - print(TFMT, f.treatment().instructions()); 198 + print(TFMT, f.treatment());
199 } 199 }
200 } 200 }
201 } 201 }
......
...@@ -17,7 +17,7 @@ package org.onosproject.net.flow; ...@@ -17,7 +17,7 @@ package org.onosproject.net.flow;
17 17
18 import com.google.common.base.MoreObjects; 18 import com.google.common.base.MoreObjects;
19 import com.google.common.collect.ImmutableList; 19 import com.google.common.collect.ImmutableList;
20 - 20 +import com.google.common.collect.Lists;
21 import org.onlab.packet.IpAddress; 21 import org.onlab.packet.IpAddress;
22 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
23 import org.onlab.packet.MplsLabel; 23 import org.onlab.packet.MplsLabel;
...@@ -27,7 +27,6 @@ import org.onosproject.net.PortNumber; ...@@ -27,7 +27,6 @@ import org.onosproject.net.PortNumber;
27 import org.onosproject.net.flow.instructions.Instruction; 27 import org.onosproject.net.flow.instructions.Instruction;
28 import org.onosproject.net.flow.instructions.Instructions; 28 import org.onosproject.net.flow.instructions.Instructions;
29 29
30 -import java.util.LinkedList;
31 import java.util.List; 30 import java.util.List;
32 import java.util.Objects; 31 import java.util.Objects;
33 32
...@@ -36,7 +35,11 @@ import java.util.Objects; ...@@ -36,7 +35,11 @@ import java.util.Objects;
36 */ 35 */
37 public final class DefaultTrafficTreatment implements TrafficTreatment { 36 public final class DefaultTrafficTreatment implements TrafficTreatment {
38 37
39 - private final List<Instruction> instructions; 38 + private final List<Instruction> immediate;
39 + private final List<Instruction> deferred;
40 + private final Instructions.TableTypeTransition table;
41 +
42 + private final boolean hasClear;
40 43
41 /** 44 /**
42 * Creates a new traffic treatment from the specified list of instructions. 45 * Creates a new traffic treatment from the specified list of instructions.
...@@ -44,12 +47,46 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -44,12 +47,46 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
44 * @param instructions treatment instructions 47 * @param instructions treatment instructions
45 */ 48 */
46 private DefaultTrafficTreatment(List<Instruction> instructions) { 49 private DefaultTrafficTreatment(List<Instruction> instructions) {
47 - this.instructions = ImmutableList.copyOf(instructions); 50 + this.immediate = ImmutableList.copyOf(instructions);
51 + this.deferred = ImmutableList.of();
52 + this.hasClear = false;
53 + this.table = null;
54 + }
55 +
56 + private DefaultTrafficTreatment(List<Instruction> deferred,
57 + List<Instruction> immediate,
58 + Instructions.TableTypeTransition table,
59 + boolean clear) {
60 + this.immediate = ImmutableList.copyOf(immediate);
61 + this.deferred = ImmutableList.copyOf(deferred);
62 + this.table = table;
63 + this.hasClear = clear;
64 +
48 } 65 }
49 66
50 @Override 67 @Override
51 public List<Instruction> instructions() { 68 public List<Instruction> instructions() {
52 - return instructions; 69 + return immediate;
70 + }
71 +
72 + @Override
73 + public List<Instruction> deferred() {
74 + return deferred;
75 + }
76 +
77 + @Override
78 + public List<Instruction> immediate() {
79 + return immediate;
80 + }
81 +
82 + @Override
83 + public Instructions.TableTypeTransition tableTransition() {
84 + return table;
85 + }
86 +
87 + @Override
88 + public Boolean clearedDeferred() {
89 + return hasClear;
53 } 90 }
54 91
55 /** 92 /**
...@@ -75,7 +112,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -75,7 +112,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
75 //FIXME: Order of instructions may affect hashcode 112 //FIXME: Order of instructions may affect hashcode
76 @Override 113 @Override
77 public int hashCode() { 114 public int hashCode() {
78 - return Objects.hash(instructions); 115 + return Objects.hash(immediate, deferred, table);
79 } 116 }
80 117
81 @Override 118 @Override
...@@ -85,7 +122,9 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -85,7 +122,9 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
85 } 122 }
86 if (obj instanceof DefaultTrafficTreatment) { 123 if (obj instanceof DefaultTrafficTreatment) {
87 DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj; 124 DefaultTrafficTreatment that = (DefaultTrafficTreatment) obj;
88 - return Objects.equals(instructions, that.instructions); 125 + return Objects.equals(immediate, that.immediate) &&
126 + Objects.equals(deferred, that.deferred) &&
127 + Objects.equals(table, that.table);
89 128
90 } 129 }
91 return false; 130 return false;
...@@ -94,7 +133,10 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -94,7 +133,10 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
94 @Override 133 @Override
95 public String toString() { 134 public String toString() {
96 return MoreObjects.toStringHelper(getClass()) 135 return MoreObjects.toStringHelper(getClass())
97 - .add("instructions", instructions) 136 + .add("immediate", immediate)
137 + .add("deferred", deferred)
138 + .add("transition", table == null ? "None" : table.toString())
139 + .add("cleared", hasClear)
98 .toString(); 140 .toString();
99 } 141 }
100 142
...@@ -106,19 +148,22 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -106,19 +148,22 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
106 148
107 boolean drop = false; 149 boolean drop = false;
108 150
109 - List<Instruction> outputs = new LinkedList<>(); 151 + boolean clear = false;
152 +
153 + Instructions.TableTypeTransition table;
110 154
111 - // TODO: should be a list of instructions based on group objects 155 + List<Instruction> deferred = Lists.newLinkedList();
112 - List<Instruction> groups = new LinkedList<>();
113 156
114 - // TODO: should be a list of instructions based on modification objects 157 + List<Instruction> immediate = Lists.newLinkedList();
115 - List<Instruction> modifications = new LinkedList<>(); 158 +
159 + List<Instruction> current = immediate;
116 160
117 // Creates a new builder 161 // Creates a new builder
118 private Builder() { 162 private Builder() {
119 } 163 }
120 164
121 // Creates a new builder based off an existing treatment 165 // Creates a new builder based off an existing treatment
166 + //FIXME only works for immediate instruction sets.
122 private Builder(TrafficTreatment treatment) { 167 private Builder(TrafficTreatment treatment) {
123 for (Instruction instruction : treatment.instructions()) { 168 for (Instruction instruction : treatment.instructions()) {
124 add(instruction); 169 add(instruction);
...@@ -127,30 +172,26 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -127,30 +172,26 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
127 172
128 @Override 173 @Override
129 public Builder add(Instruction instruction) { 174 public Builder add(Instruction instruction) {
130 - if (drop) { 175 +
131 - return this;
132 - }
133 switch (instruction.type()) { 176 switch (instruction.type()) {
134 case DROP: 177 case DROP:
135 - drop = true;
136 - break;
137 - case TABLE:
138 case OUTPUT: 178 case OUTPUT:
139 - outputs.add(instruction); 179 + case GROUP:
140 - break;
141 case L0MODIFICATION: 180 case L0MODIFICATION:
142 case L2MODIFICATION: 181 case L2MODIFICATION:
143 case L3MODIFICATION: 182 case L3MODIFICATION:
144 - // TODO: enforce modification order if any 183 + current.add(instruction);
145 - modifications.add(instruction);
146 break; 184 break;
147 - case GROUP: 185 + case TABLE:
148 - groups.add(instruction); 186 + table = (Instructions.TableTypeTransition) instruction;
149 break; 187 break;
150 default: 188 default:
151 throw new IllegalArgumentException("Unknown instruction type: " + 189 throw new IllegalArgumentException("Unknown instruction type: " +
152 instruction.type()); 190 instruction.type());
191 +
192 +
153 } 193 }
194 +
154 return this; 195 return this;
155 } 196 }
156 197
...@@ -254,27 +295,40 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -254,27 +295,40 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
254 } 295 }
255 296
256 @Override 297 @Override
257 - public TrafficTreatment.Builder transition(FlowRule.Type type) { 298 + public Builder popVlan() {
299 + return add(Instructions.popVlan());
300 + }
301 +
302 + @Override
303 + public Builder transition(FlowRule.Type type) {
258 return add(Instructions.transition(type)); 304 return add(Instructions.transition(type));
259 } 305 }
260 306
261 @Override 307 @Override
262 - public Builder popVlan() { 308 + public Builder immediate() {
263 - return add(Instructions.popVlan()); 309 + current = immediate;
310 + return this;
264 } 311 }
265 312
266 @Override 313 @Override
267 - public TrafficTreatment build() { 314 + public Builder deferred() {
315 + current = deferred;
316 + return this;
317 + }
268 318
269 - //If we are dropping should we just return an empty list? 319 + @Override
270 - List<Instruction> instructions = new LinkedList<Instruction>(); 320 + public Builder wipeDeferred() {
271 - instructions.addAll(modifications); 321 + clear = true;
272 - instructions.addAll(groups); 322 + return this;
273 - if (!drop) { 323 + }
274 - instructions.addAll(outputs);
275 - }
276 324
277 - return new DefaultTrafficTreatment(instructions); 325 + @Override
326 + public TrafficTreatment build() {
327 + if (deferred.size() == 0 && immediate.size() == 0
328 + && table == null && !clear) {
329 + drop();
330 + }
331 + return new DefaultTrafficTreatment(deferred, immediate, table, clear);
278 } 332 }
279 333
280 } 334 }
......
...@@ -25,6 +25,7 @@ import org.onlab.packet.IpAddress; ...@@ -25,6 +25,7 @@ import org.onlab.packet.IpAddress;
25 import org.onlab.packet.MacAddress; 25 import org.onlab.packet.MacAddress;
26 import org.onlab.packet.MplsLabel; 26 import org.onlab.packet.MplsLabel;
27 import org.onlab.packet.VlanId; 27 import org.onlab.packet.VlanId;
28 +import org.onosproject.net.flow.instructions.Instructions;
28 29
29 /** 30 /**
30 * Abstraction of network traffic treatment. 31 * Abstraction of network traffic treatment.
...@@ -36,9 +37,37 @@ public interface TrafficTreatment { ...@@ -36,9 +37,37 @@ public interface TrafficTreatment {
36 * 37 *
37 * @return list of treatment instructions 38 * @return list of treatment instructions
38 */ 39 */
40 + @Deprecated
39 List<Instruction> instructions(); 41 List<Instruction> instructions();
40 42
41 /** 43 /**
44 + * Returns the list of treatment instructions that will be applied
45 + * further down the pipeline.
46 + * @return list of treatment instructions
47 + */
48 + List<Instruction> deferred();
49 +
50 + /**
51 + * Returns the list of treatment instructions that will be applied
52 + * immediately.
53 + * @return list of treatment instructions
54 + */
55 + List<Instruction> immediate();
56 +
57 + /**
58 + * Returns the next table in the pipeline.
59 + * @return a table transition; may be null.
60 + */
61 + Instructions.TableTypeTransition tableTransition();
62 +
63 + /**
64 + * Whether the deferred treatment instructions will be cleared
65 + * by the device.
66 + * @return a boolean
67 + */
68 + Boolean clearedDeferred();
69 +
70 + /**
42 * Builder of traffic treatment entities. 71 * Builder of traffic treatment entities.
43 */ 72 */
44 public interface Builder { 73 public interface Builder {
...@@ -218,6 +247,25 @@ public interface TrafficTreatment { ...@@ -218,6 +247,25 @@ public interface TrafficTreatment {
218 public Builder popVlan(); 247 public Builder popVlan();
219 248
220 /** 249 /**
250 + * Any instructions preceded by this method call will be deferred.
251 + * @return a treatment builder
252 + */
253 + public Builder deferred();
254 +
255 + /**
256 + * Any instructions preceded by this method call will be immediate.
257 + * @return a treatment builder
258 + */
259 + public Builder immediate();
260 +
261 +
262 + /**
263 + * Instructs the device to clear the deferred instructions set.
264 + * @return a treatment builder
265 + */
266 + public Builder wipeDeferred();
267 +
268 + /**
221 * Builds an immutable traffic treatment descriptor. 269 * Builds an immutable traffic treatment descriptor.
222 * 270 *
223 * @return traffic treatment 271 * @return traffic treatment
......
...@@ -295,7 +295,7 @@ public final class Instructions { ...@@ -295,7 +295,7 @@ public final class Instructions {
295 295
296 @Override 296 @Override
297 public String toString() { 297 public String toString() {
298 - return toStringHelper(type()).toString(); 298 + return toStringHelper(type().toString()).toString();
299 299
300 } 300 }
301 301
......
...@@ -15,17 +15,16 @@ ...@@ -15,17 +15,16 @@
15 */ 15 */
16 package org.onosproject.net.flow; 16 package org.onosproject.net.flow;
17 17
18 -import java.util.List; 18 +import com.google.common.testing.EqualsTester;
19 -
20 import org.junit.Test; 19 import org.junit.Test;
21 -import org.onosproject.net.PortNumber;
22 -import org.onosproject.net.flow.instructions.Instruction;
23 -import org.onosproject.net.flow.instructions.Instructions;
24 import org.onlab.packet.IpAddress; 20 import org.onlab.packet.IpAddress;
25 import org.onlab.packet.MacAddress; 21 import org.onlab.packet.MacAddress;
26 import org.onlab.packet.VlanId; 22 import org.onlab.packet.VlanId;
23 +import org.onosproject.net.PortNumber;
24 +import org.onosproject.net.flow.instructions.Instruction;
25 +import org.onosproject.net.flow.instructions.Instructions;
27 26
28 -import com.google.common.testing.EqualsTester; 27 +import java.util.List;
29 28
30 import static org.hamcrest.CoreMatchers.equalTo; 29 import static org.hamcrest.CoreMatchers.equalTo;
31 import static org.hamcrest.MatcherAssert.assertThat; 30 import static org.hamcrest.MatcherAssert.assertThat;
...@@ -83,7 +82,7 @@ public class DefaultTrafficTreatmentTest { ...@@ -83,7 +82,7 @@ public class DefaultTrafficTreatmentTest {
83 builder1.add(instruction1); 82 builder1.add(instruction1);
84 83
85 final List<Instruction> instructions2 = builder1.build().instructions(); 84 final List<Instruction> instructions2 = builder1.build().instructions();
86 - assertThat(instructions2, hasSize(8)); 85 + assertThat(instructions2, hasSize(11));
87 } 86 }
88 87
89 /** 88 /**
......
...@@ -45,6 +45,7 @@ import org.onosproject.net.flow.TrafficTreatment; ...@@ -45,6 +45,7 @@ import org.onosproject.net.flow.TrafficTreatment;
45 import org.onosproject.net.flow.criteria.Criterion; 45 import org.onosproject.net.flow.criteria.Criterion;
46 import org.onosproject.net.flow.criteria.Criterion.Type; 46 import org.onosproject.net.flow.criteria.Criterion.Type;
47 import org.onosproject.net.flow.instructions.Instruction; 47 import org.onosproject.net.flow.instructions.Instruction;
48 +import org.onosproject.net.flow.instructions.Instructions;
48 import org.onosproject.net.resource.Bandwidth; 49 import org.onosproject.net.resource.Bandwidth;
49 import org.onosproject.net.resource.BandwidthResourceRequest; 50 import org.onosproject.net.resource.BandwidthResourceRequest;
50 import org.onosproject.net.resource.Lambda; 51 import org.onosproject.net.resource.Lambda;
...@@ -96,6 +97,26 @@ public class IntentTestsMocks { ...@@ -96,6 +97,26 @@ public class IntentTestsMocks {
96 public List<Instruction> instructions() { 97 public List<Instruction> instructions() {
97 return new ArrayList<>(); 98 return new ArrayList<>();
98 } 99 }
100 +
101 + @Override
102 + public List<Instruction> deferred() {
103 + return null;
104 + }
105 +
106 + @Override
107 + public List<Instruction> immediate() {
108 + return null;
109 + }
110 +
111 + @Override
112 + public Instructions.TableTypeTransition tableTransition() {
113 + return null;
114 + }
115 +
116 + @Override
117 + public Boolean clearedDeferred() {
118 + return null;
119 + }
99 } 120 }
100 121
101 /** 122 /**
......
...@@ -63,6 +63,7 @@ import org.onosproject.net.flow.TrafficSelector; ...@@ -63,6 +63,7 @@ import org.onosproject.net.flow.TrafficSelector;
63 import org.onosproject.net.flow.TrafficTreatment; 63 import org.onosproject.net.flow.TrafficTreatment;
64 import org.onosproject.net.flow.criteria.Criterion; 64 import org.onosproject.net.flow.criteria.Criterion;
65 import org.onosproject.net.flow.instructions.Instruction; 65 import org.onosproject.net.flow.instructions.Instruction;
66 +import org.onosproject.net.flow.instructions.Instructions;
66 import org.onosproject.net.provider.AbstractProvider; 67 import org.onosproject.net.provider.AbstractProvider;
67 import org.onosproject.net.provider.ProviderId; 68 import org.onosproject.net.provider.ProviderId;
68 import org.onosproject.store.trivial.impl.SimpleFlowRuleStore; 69 import org.onosproject.store.trivial.impl.SimpleFlowRuleStore;
...@@ -562,6 +563,26 @@ public class FlowRuleManagerTest { ...@@ -562,6 +563,26 @@ public class FlowRuleManagerTest {
562 } 563 }
563 564
564 @Override 565 @Override
566 + public List<Instruction> deferred() {
567 + return null;
568 + }
569 +
570 + @Override
571 + public List<Instruction> immediate() {
572 + return null;
573 + }
574 +
575 + @Override
576 + public Instructions.TableTypeTransition tableTransition() {
577 + return null;
578 + }
579 +
580 + @Override
581 + public Boolean clearedDeferred() {
582 + return null;
583 + }
584 +
585 + @Override
565 public int hashCode() { 586 public int hashCode() {
566 return testval; 587 return testval;
567 } 588 }
......
...@@ -16,13 +16,14 @@ ...@@ -16,13 +16,14 @@
16 package org.onosproject.store.statistic.impl; 16 package org.onosproject.store.statistic.impl;
17 17
18 import com.google.common.collect.Sets; 18 import com.google.common.collect.Sets;
19 - 19 +import org.apache.commons.collections.ListUtils;
20 import org.apache.felix.scr.annotations.Activate; 20 import org.apache.felix.scr.annotations.Activate;
21 import org.apache.felix.scr.annotations.Component; 21 import org.apache.felix.scr.annotations.Component;
22 import org.apache.felix.scr.annotations.Deactivate; 22 import org.apache.felix.scr.annotations.Deactivate;
23 import org.apache.felix.scr.annotations.Reference; 23 import org.apache.felix.scr.annotations.Reference;
24 import org.apache.felix.scr.annotations.ReferenceCardinality; 24 import org.apache.felix.scr.annotations.ReferenceCardinality;
25 import org.apache.felix.scr.annotations.Service; 25 import org.apache.felix.scr.annotations.Service;
26 +import org.onlab.util.KryoNamespace;
26 import org.onosproject.cluster.ClusterService; 27 import org.onosproject.cluster.ClusterService;
27 import org.onosproject.net.ConnectPoint; 28 import org.onosproject.net.ConnectPoint;
28 import org.onosproject.net.DeviceId; 29 import org.onosproject.net.DeviceId;
...@@ -39,12 +40,12 @@ import org.onosproject.store.flow.ReplicaInfo; ...@@ -39,12 +40,12 @@ import org.onosproject.store.flow.ReplicaInfo;
39 import org.onosproject.store.flow.ReplicaInfoService; 40 import org.onosproject.store.flow.ReplicaInfoService;
40 import org.onosproject.store.serializers.KryoNamespaces; 41 import org.onosproject.store.serializers.KryoNamespaces;
41 import org.onosproject.store.serializers.KryoSerializer; 42 import org.onosproject.store.serializers.KryoSerializer;
42 -import org.onlab.util.KryoNamespace;
43 import org.slf4j.Logger; 43 import org.slf4j.Logger;
44 44
45 import java.io.IOException; 45 import java.io.IOException;
46 import java.util.Collections; 46 import java.util.Collections;
47 import java.util.HashSet; 47 import java.util.HashSet;
48 +import java.util.List;
48 import java.util.Map; 49 import java.util.Map;
49 import java.util.Set; 50 import java.util.Set;
50 import java.util.concurrent.ConcurrentHashMap; 51 import java.util.concurrent.ConcurrentHashMap;
...@@ -305,7 +306,9 @@ public class DistributedStatisticStore implements StatisticStore { ...@@ -305,7 +306,9 @@ public class DistributedStatisticStore implements StatisticStore {
305 } 306 }
306 307
307 private PortNumber getOutput(FlowRule rule) { 308 private PortNumber getOutput(FlowRule rule) {
308 - for (Instruction i : rule.treatment().instructions()) { 309 + List<Instruction> all = ListUtils.union(rule.treatment().immediate(),
310 + rule.treatment().deferred());
311 + for (Instruction i : all) {
309 if (i.type() == Instruction.Type.OUTPUT) { 312 if (i.type() == Instruction.Type.OUTPUT) {
310 Instructions.OutputInstruction out = (Instructions.OutputInstruction) i; 313 Instructions.OutputInstruction out = (Instructions.OutputInstruction) i;
311 return out.port(); 314 return out.port();
......
...@@ -205,7 +205,7 @@ public abstract class FlowModBuilder { ...@@ -205,7 +205,7 @@ public abstract class FlowModBuilder {
205 OFVlanVidMatch.PRESENT); 205 OFVlanVidMatch.PRESENT);
206 } else { 206 } else {
207 mBuilder.setExact(MatchField.VLAN_VID, 207 mBuilder.setExact(MatchField.VLAN_VID,
208 - OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort()))); 208 + OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
209 } 209 }
210 break; 210 break;
211 case VLAN_PCP: 211 case VLAN_PCP:
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.provider.of.flow.impl; 16 package org.onosproject.provider.of.flow.impl;
17 17
18 +import com.google.common.collect.Lists;
18 import org.onlab.packet.Ip4Address; 19 import org.onlab.packet.Ip4Address;
19 import org.onlab.packet.Ip6Address; 20 import org.onlab.packet.Ip6Address;
20 import org.onosproject.net.PortNumber; 21 import org.onosproject.net.PortNumber;
...@@ -95,18 +96,22 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -95,18 +96,22 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
95 @Override 96 @Override
96 public OFFlowAdd buildFlowAdd() { 97 public OFFlowAdd buildFlowAdd() {
97 Match match = buildMatch(); 98 Match match = buildMatch();
98 - List<OFAction> actions = buildActions(); 99 + List<OFAction> deferredActions = buildActions(treatment.deferred());
99 - List<OFInstruction> instructions = buildInstructions(); 100 + List<OFAction> immediateActions = buildActions(treatment.immediate());
100 - 101 + List<OFInstruction> instructions = Lists.newLinkedList();
101 - // FIXME had to revert back to using apply-actions instead of 102 +
102 - // write-actions because LINC-OE apparently doesn't support 103 +
103 - // write-actions. I would prefer to change this back in the future 104 + if (immediateActions.size() > 0) {
104 - // because apply-actions is an optional instruction in OF 1.3. 105 + instructions.add(factory().instructions().applyActions(immediateActions));
105 - 106 + }
106 - if (actions != null) { 107 + if (treatment.clearedDeferred()) {
107 - OFInstruction applyActions = 108 + instructions.add(factory().instructions().clearActions());
108 - factory().instructions().applyActions(actions); 109 + }
109 - instructions.add(applyActions); 110 + if (deferredActions.size() > 0) {
111 + instructions.add(factory().instructions().writeActions(deferredActions));
112 + }
113 + if (treatment.tableTransition() != null) {
114 + instructions.add(buildTableGoto(treatment.tableTransition()));
110 } 115 }
111 116
112 long cookie = flowRule().id().value(); 117 long cookie = flowRule().id().value();
...@@ -128,13 +133,22 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -128,13 +133,22 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
128 @Override 133 @Override
129 public OFFlowMod buildFlowMod() { 134 public OFFlowMod buildFlowMod() {
130 Match match = buildMatch(); 135 Match match = buildMatch();
131 - List<OFAction> actions = buildActions(); 136 + List<OFAction> deferredActions = buildActions(treatment.deferred());
132 - List<OFInstruction> instructions = buildInstructions(); 137 + List<OFAction> immediateActions = buildActions(treatment.immediate());
138 + List<OFInstruction> instructions = Lists.newLinkedList();
139 +
133 140
134 - if (actions != null) { 141 + if (immediateActions.size() > 0) {
135 - OFInstruction applyActions = 142 + instructions.add(factory().instructions().applyActions(immediateActions));
136 - factory().instructions().applyActions(actions); 143 + }
137 - instructions.add(applyActions); 144 + if (treatment.clearedDeferred()) {
145 + instructions.add(factory().instructions().clearActions());
146 + }
147 + if (deferredActions.size() > 0) {
148 + instructions.add(factory().instructions().writeActions(deferredActions));
149 + }
150 + if (treatment.tableTransition() != null) {
151 + instructions.add(buildTableGoto(treatment.tableTransition()));
138 } 152 }
139 153
140 long cookie = flowRule().id().value(); 154 long cookie = flowRule().id().value();
...@@ -189,13 +203,13 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -189,13 +203,13 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
189 return instructions; 203 return instructions;
190 } 204 }
191 205
192 - private List<OFAction> buildActions() { 206 + private List<OFAction> buildActions(List<Instruction> treatments) {
193 List<OFAction> actions = new LinkedList<>(); 207 List<OFAction> actions = new LinkedList<>();
194 boolean tableFound = false; 208 boolean tableFound = false;
195 if (treatment == null) { 209 if (treatment == null) {
196 return actions; 210 return actions;
197 } 211 }
198 - for (Instruction i : treatment.instructions()) { 212 + for (Instruction i : treatments) {
199 switch (i.type()) { 213 switch (i.type()) {
200 case DROP: 214 case DROP:
201 log.warn("Saw drop action; assigning drop action"); 215 log.warn("Saw drop action; assigning drop action");
...@@ -320,7 +334,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -320,7 +334,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
320 return factory().actions().popMpls(EthType.of(popHeaderInstructions 334 return factory().actions().popMpls(EthType.of(popHeaderInstructions
321 .ethernetType())); 335 .ethernetType()));
322 case STRIP_VLAN: 336 case STRIP_VLAN:
323 - return factory().actions().stripVlan(); 337 + return factory().actions().popVlan();
324 case MPLS_LABEL: 338 case MPLS_LABEL:
325 ModMplsLabelInstruction mplsLabel = 339 ModMplsLabelInstruction mplsLabel =
326 (ModMplsLabelInstruction) l2m; 340 (ModMplsLabelInstruction) l2m;
......
...@@ -380,7 +380,7 @@ public final class IntentJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> ...@@ -380,7 +380,7 @@ public final class IntentJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode>
380 380
381 for (Instruction instruction : instructions) { 381 for (Instruction instruction : instructions) {
382 boolean instructionFound = false; 382 boolean instructionFound = false;
383 - for (int instructionIndex = 0; instructionIndex < jsonCriteria.size(); instructionIndex++) { 383 + for (int instructionIndex = 0; instructionIndex < jsonInstructions.size(); instructionIndex++) {
384 final InstructionJsonMatcher instructionMatcher = 384 final InstructionJsonMatcher instructionMatcher =
385 InstructionJsonMatcher.matchesInstruction(instruction); 385 InstructionJsonMatcher.matchesInstruction(instruction);
386 if (instructionMatcher.matches(jsonInstructions.get(instructionIndex))) { 386 if (instructionMatcher.matches(jsonInstructions.get(instructionIndex))) {
......