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
Showing
13 changed files
with
240 additions
and
78 deletions
... | @@ -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(); | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -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: | ... | ... |
providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
... | @@ -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))) { | ... | ... |
-
Please register or login to post a comment