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
399 additions
and
189 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(); | ... | ... |
... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
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 com.google.common.collect.Lists; |
19 | - | ||
20 | import org.onlab.packet.Ip4Address; | 19 | import org.onlab.packet.Ip4Address; |
21 | import org.onlab.packet.Ip4Prefix; | 20 | import org.onlab.packet.Ip4Prefix; |
22 | import org.onlab.packet.Ip6Address; | 21 | import org.onlab.packet.Ip6Address; |
... | @@ -41,7 +40,6 @@ import org.onosproject.openflow.controller.Dpid; | ... | @@ -41,7 +40,6 @@ import org.onosproject.openflow.controller.Dpid; |
41 | import org.projectfloodlight.openflow.protocol.OFFlowMod; | 40 | import org.projectfloodlight.openflow.protocol.OFFlowMod; |
42 | import org.projectfloodlight.openflow.protocol.OFFlowRemoved; | 41 | import org.projectfloodlight.openflow.protocol.OFFlowRemoved; |
43 | import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; | 42 | import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; |
44 | -import org.projectfloodlight.openflow.protocol.OFInstructionType; | ||
45 | import org.projectfloodlight.openflow.protocol.action.OFAction; | 43 | import org.projectfloodlight.openflow.protocol.action.OFAction; |
46 | import org.projectfloodlight.openflow.protocol.action.OFActionCircuit; | 44 | import org.projectfloodlight.openflow.protocol.action.OFActionCircuit; |
47 | import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; | 45 | import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter; |
... | @@ -57,10 +55,12 @@ import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp; | ... | @@ -57,10 +55,12 @@ import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanPcp; |
57 | import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid; | 55 | import org.projectfloodlight.openflow.protocol.action.OFActionSetVlanVid; |
58 | import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; | 56 | import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; |
59 | import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; | 57 | import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; |
58 | +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionWriteActions; | ||
60 | import org.projectfloodlight.openflow.protocol.match.Match; | 59 | import org.projectfloodlight.openflow.protocol.match.Match; |
61 | import org.projectfloodlight.openflow.protocol.match.MatchField; | 60 | import org.projectfloodlight.openflow.protocol.match.MatchField; |
62 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; | 61 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; |
63 | import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic; | 62 | import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic; |
63 | +import org.projectfloodlight.openflow.protocol.ver13.OFFactoryVer13; | ||
64 | import org.projectfloodlight.openflow.types.IPv4Address; | 64 | import org.projectfloodlight.openflow.types.IPv4Address; |
65 | import org.projectfloodlight.openflow.types.IPv6Address; | 65 | import org.projectfloodlight.openflow.types.IPv6Address; |
66 | import org.projectfloodlight.openflow.types.Masked; | 66 | import org.projectfloodlight.openflow.types.Masked; |
... | @@ -81,7 +81,12 @@ public class FlowEntryBuilder { | ... | @@ -81,7 +81,12 @@ public class FlowEntryBuilder { |
81 | private final OFFlowMod flowMod; | 81 | private final OFFlowMod flowMod; |
82 | 82 | ||
83 | private final Match match; | 83 | private final Match match; |
84 | - private final List<OFAction> actions; | 84 | + |
85 | + /* | ||
86 | + All actions are contained in an OFInstruction. For OF1.0 | ||
87 | + the instruction type is apply instruction (immediate set in ONOS speak) | ||
88 | + */ | ||
89 | + private final List<OFInstruction> instructions; | ||
85 | 90 | ||
86 | private final Dpid dpid; | 91 | private final Dpid dpid; |
87 | 92 | ||
... | @@ -94,7 +99,7 @@ public class FlowEntryBuilder { | ... | @@ -94,7 +99,7 @@ public class FlowEntryBuilder { |
94 | public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) { | 99 | public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) { |
95 | this.stat = entry; | 100 | this.stat = entry; |
96 | this.match = entry.getMatch(); | 101 | this.match = entry.getMatch(); |
97 | - this.actions = getActions(entry); | 102 | + this.instructions = getInstructions(entry); |
98 | this.dpid = dpid; | 103 | this.dpid = dpid; |
99 | this.removed = null; | 104 | this.removed = null; |
100 | this.flowMod = null; | 105 | this.flowMod = null; |
... | @@ -104,7 +109,7 @@ public class FlowEntryBuilder { | ... | @@ -104,7 +109,7 @@ public class FlowEntryBuilder { |
104 | public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry, Type tableType) { | 109 | public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry, Type tableType) { |
105 | this.stat = entry; | 110 | this.stat = entry; |
106 | this.match = entry.getMatch(); | 111 | this.match = entry.getMatch(); |
107 | - this.actions = getActions(entry); | 112 | + this.instructions = getInstructions(entry); |
108 | this.dpid = dpid; | 113 | this.dpid = dpid; |
109 | this.removed = null; | 114 | this.removed = null; |
110 | this.flowMod = null; | 115 | this.flowMod = null; |
... | @@ -117,7 +122,7 @@ public class FlowEntryBuilder { | ... | @@ -117,7 +122,7 @@ public class FlowEntryBuilder { |
117 | this.removed = removed; | 122 | this.removed = removed; |
118 | 123 | ||
119 | this.dpid = dpid; | 124 | this.dpid = dpid; |
120 | - this.actions = null; | 125 | + this.instructions = null; |
121 | this.stat = null; | 126 | this.stat = null; |
122 | this.flowMod = null; | 127 | this.flowMod = null; |
123 | this.type = FlowType.REMOVED; | 128 | this.type = FlowType.REMOVED; |
... | @@ -127,7 +132,7 @@ public class FlowEntryBuilder { | ... | @@ -127,7 +132,7 @@ public class FlowEntryBuilder { |
127 | public FlowEntryBuilder(Dpid dpid, OFFlowMod fm) { | 132 | public FlowEntryBuilder(Dpid dpid, OFFlowMod fm) { |
128 | this.match = fm.getMatch(); | 133 | this.match = fm.getMatch(); |
129 | this.dpid = dpid; | 134 | this.dpid = dpid; |
130 | - this.actions = fm.getActions(); | 135 | + this.instructions = getInstructions(fm); |
131 | this.type = FlowType.MOD; | 136 | this.type = FlowType.MOD; |
132 | this.flowMod = fm; | 137 | this.flowMod = fm; |
133 | this.stat = null; | 138 | this.stat = null; |
... | @@ -164,21 +169,30 @@ public class FlowEntryBuilder { | ... | @@ -164,21 +169,30 @@ public class FlowEntryBuilder { |
164 | 169 | ||
165 | } | 170 | } |
166 | 171 | ||
167 | - private List<OFAction> getActions(OFFlowStatsEntry entry) { | 172 | + private List<OFInstruction> getInstructions(OFFlowMod entry) { |
168 | switch (entry.getVersion()) { | 173 | switch (entry.getVersion()) { |
169 | case OF_10: | 174 | case OF_10: |
170 | - return entry.getActions(); | 175 | + return Lists.newArrayList( |
176 | + OFFactoryVer13.INSTANCE.instructions().applyActions(entry.getActions())); | ||
171 | case OF_11: | 177 | case OF_11: |
172 | case OF_12: | 178 | case OF_12: |
173 | case OF_13: | 179 | case OF_13: |
174 | - List<OFInstruction> ins = entry.getInstructions(); | 180 | + return entry.getInstructions(); |
175 | - for (OFInstruction in : ins) { | 181 | + default: |
176 | - if (in.getType().equals(OFInstructionType.APPLY_ACTIONS)) { | 182 | + log.warn("Unknown OF version {}", entry.getVersion()); |
177 | - OFInstructionApplyActions apply = (OFInstructionApplyActions) in; | 183 | + } |
178 | - return apply.getActions(); | 184 | + return Lists.newLinkedList(); |
179 | - } | 185 | + } |
180 | - } | 186 | + |
181 | - return Lists.newLinkedList(); | 187 | + private List<OFInstruction> getInstructions(OFFlowStatsEntry entry) { |
188 | + switch (entry.getVersion()) { | ||
189 | + case OF_10: | ||
190 | + return Lists.newArrayList( | ||
191 | + OFFactoryVer13.INSTANCE.instructions().applyActions(entry.getActions())); | ||
192 | + case OF_11: | ||
193 | + case OF_12: | ||
194 | + case OF_13: | ||
195 | + return entry.getInstructions(); | ||
182 | default: | 196 | default: |
183 | log.warn("Unknown OF version {}", entry.getVersion()); | 197 | log.warn("Unknown OF version {}", entry.getVersion()); |
184 | } | 198 | } |
... | @@ -188,111 +202,145 @@ public class FlowEntryBuilder { | ... | @@ -188,111 +202,145 @@ public class FlowEntryBuilder { |
188 | private TrafficTreatment buildTreatment() { | 202 | private TrafficTreatment buildTreatment() { |
189 | TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); | 203 | TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); |
190 | // If this is a drop rule | 204 | // If this is a drop rule |
191 | - if (actions.size() == 0) { | 205 | + if (instructions.size() == 0) { |
192 | builder.drop(); | 206 | builder.drop(); |
193 | return builder.build(); | 207 | return builder.build(); |
194 | } | 208 | } |
209 | + for (OFInstruction in : instructions) { | ||
210 | + switch (in.getType()) { | ||
211 | + case GOTO_TABLE: | ||
212 | + builder.transition(tableType); | ||
213 | + break; | ||
214 | + case WRITE_METADATA: | ||
215 | + break; | ||
216 | + case WRITE_ACTIONS: | ||
217 | + builder.deferred(); | ||
218 | + buildActions(((OFInstructionWriteActions) in).getActions(), | ||
219 | + builder); | ||
220 | + break; | ||
221 | + case APPLY_ACTIONS: | ||
222 | + builder.immediate(); | ||
223 | + buildActions(((OFInstructionApplyActions) in).getActions(), | ||
224 | + builder); | ||
225 | + break; | ||
226 | + case CLEAR_ACTIONS: | ||
227 | + builder.wipeDeferred(); | ||
228 | + break; | ||
229 | + case EXPERIMENTER: | ||
230 | + break; | ||
231 | + case METER: | ||
232 | + break; | ||
233 | + default: | ||
234 | + log.warn("Unknown instructions type {}", in.getType()); | ||
235 | + } | ||
236 | + } | ||
237 | + | ||
238 | + return builder.build(); | ||
239 | + } | ||
240 | + | ||
241 | + private TrafficTreatment.Builder buildActions(List<OFAction> actions, | ||
242 | + TrafficTreatment.Builder builder) { | ||
195 | for (OFAction act : actions) { | 243 | for (OFAction act : actions) { |
196 | switch (act.getType()) { | 244 | switch (act.getType()) { |
197 | - case OUTPUT: | 245 | + case OUTPUT: |
198 | - OFActionOutput out = (OFActionOutput) act; | 246 | + OFActionOutput out = (OFActionOutput) act; |
199 | - builder.setOutput( | 247 | + builder.setOutput( |
200 | - PortNumber.portNumber(out.getPort().getPortNumber())); | 248 | + PortNumber.portNumber(out.getPort().getPortNumber())); |
201 | - break; | 249 | + break; |
202 | - case SET_VLAN_VID: | 250 | + case SET_VLAN_VID: |
203 | - OFActionSetVlanVid vlan = (OFActionSetVlanVid) act; | 251 | + OFActionSetVlanVid vlan = (OFActionSetVlanVid) act; |
204 | - builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan())); | 252 | + builder.setVlanId(VlanId.vlanId(vlan.getVlanVid().getVlan())); |
205 | - break; | 253 | + break; |
206 | - case SET_VLAN_PCP: | 254 | + case SET_VLAN_PCP: |
207 | - OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act; | 255 | + OFActionSetVlanPcp pcp = (OFActionSetVlanPcp) act; |
208 | - builder.setVlanPcp(pcp.getVlanPcp().getValue()); | 256 | + builder.setVlanPcp(pcp.getVlanPcp().getValue()); |
209 | - break; | 257 | + break; |
210 | - case SET_DL_DST: | 258 | + case SET_DL_DST: |
211 | - OFActionSetDlDst dldst = (OFActionSetDlDst) act; | 259 | + OFActionSetDlDst dldst = (OFActionSetDlDst) act; |
212 | - builder.setEthDst( | 260 | + builder.setEthDst( |
213 | - MacAddress.valueOf(dldst.getDlAddr().getLong())); | 261 | + MacAddress.valueOf(dldst.getDlAddr().getLong())); |
214 | - break; | 262 | + break; |
215 | - case SET_DL_SRC: | 263 | + case SET_DL_SRC: |
216 | - OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act; | 264 | + OFActionSetDlSrc dlsrc = (OFActionSetDlSrc) act; |
217 | - builder.setEthSrc( | 265 | + builder.setEthSrc( |
218 | - MacAddress.valueOf(dlsrc.getDlAddr().getLong())); | 266 | + MacAddress.valueOf(dlsrc.getDlAddr().getLong())); |
219 | 267 | ||
220 | - break; | 268 | + break; |
221 | - case SET_NW_DST: | 269 | + case SET_NW_DST: |
222 | - OFActionSetNwDst nwdst = (OFActionSetNwDst) act; | 270 | + OFActionSetNwDst nwdst = (OFActionSetNwDst) act; |
223 | - IPv4Address di = nwdst.getNwAddr(); | 271 | + IPv4Address di = nwdst.getNwAddr(); |
224 | - builder.setIpDst(Ip4Address.valueOf(di.getInt())); | 272 | + builder.setIpDst(Ip4Address.valueOf(di.getInt())); |
225 | - break; | 273 | + break; |
226 | - case SET_NW_SRC: | 274 | + case SET_NW_SRC: |
227 | - OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act; | 275 | + OFActionSetNwSrc nwsrc = (OFActionSetNwSrc) act; |
228 | - IPv4Address si = nwsrc.getNwAddr(); | 276 | + IPv4Address si = nwsrc.getNwAddr(); |
229 | - builder.setIpSrc(Ip4Address.valueOf(si.getInt())); | 277 | + builder.setIpSrc(Ip4Address.valueOf(si.getInt())); |
230 | - break; | 278 | + break; |
231 | - case EXPERIMENTER: | 279 | + case EXPERIMENTER: |
232 | - OFActionExperimenter exp = (OFActionExperimenter) act; | 280 | + OFActionExperimenter exp = (OFActionExperimenter) act; |
233 | - if (exp.getExperimenter() == 0x80005A06 || | 281 | + if (exp.getExperimenter() == 0x80005A06 || |
234 | - exp.getExperimenter() == 0x748771) { | 282 | + exp.getExperimenter() == 0x748771) { |
235 | - OFActionCircuit ct = (OFActionCircuit) exp; | 283 | + OFActionCircuit ct = (OFActionCircuit) exp; |
236 | - builder.setLambda(((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber()); | 284 | + builder.setLambda(((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber()); |
237 | - } else { | 285 | + } else { |
238 | - log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter()); | 286 | + log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter()); |
239 | - } | 287 | + } |
240 | - break; | 288 | + break; |
241 | - case SET_FIELD: | 289 | + case SET_FIELD: |
242 | - OFActionSetField setField = (OFActionSetField) act; | 290 | + OFActionSetField setField = (OFActionSetField) act; |
243 | - handleSetField(builder, setField.getField()); | 291 | + handleSetField(builder, setField.getField()); |
244 | - break; | 292 | + break; |
245 | - case POP_MPLS: | 293 | + case POP_MPLS: |
246 | - OFActionPopMpls popMpls = (OFActionPopMpls) act; | 294 | + OFActionPopMpls popMpls = (OFActionPopMpls) act; |
247 | - builder.popMpls((short) popMpls.getEthertype().getValue()); | 295 | + builder.popMpls((short) popMpls.getEthertype().getValue()); |
248 | - break; | 296 | + break; |
249 | - case PUSH_MPLS: | 297 | + case PUSH_MPLS: |
250 | - builder.pushMpls(); | 298 | + builder.pushMpls(); |
251 | - break; | 299 | + break; |
252 | - case COPY_TTL_IN: | 300 | + case COPY_TTL_IN: |
253 | - builder.copyTtlIn(); | 301 | + builder.copyTtlIn(); |
254 | - break; | 302 | + break; |
255 | - case COPY_TTL_OUT: | 303 | + case COPY_TTL_OUT: |
256 | - builder.copyTtlOut(); | 304 | + builder.copyTtlOut(); |
257 | - break; | 305 | + break; |
258 | - case DEC_MPLS_TTL: | 306 | + case DEC_MPLS_TTL: |
259 | - builder.decMplsTtl(); | 307 | + builder.decMplsTtl(); |
260 | - break; | 308 | + break; |
261 | - case DEC_NW_TTL: | 309 | + case DEC_NW_TTL: |
262 | - builder.decNwTtl(); | 310 | + builder.decNwTtl(); |
263 | - break; | 311 | + break; |
264 | - case GROUP: | 312 | + case GROUP: |
265 | - OFActionGroup group = (OFActionGroup) act; | 313 | + OFActionGroup group = (OFActionGroup) act; |
266 | - builder.group(new DefaultGroupId(group.getGroup().getGroupNumber())); | 314 | + builder.group(new DefaultGroupId(group.getGroup().getGroupNumber())); |
267 | - break; | 315 | + break; |
268 | - case POP_VLAN: | 316 | + case POP_VLAN: |
269 | - builder.popVlan(); | 317 | + builder.popVlan(); |
270 | - break; | 318 | + break; |
271 | - case STRIP_VLAN: | 319 | + case STRIP_VLAN: |
272 | - builder.stripVlan(); | 320 | + builder.stripVlan(); |
273 | - break; | 321 | + break; |
274 | - case SET_TP_DST: | 322 | + case SET_TP_DST: |
275 | - case SET_TP_SRC: | 323 | + case SET_TP_SRC: |
276 | - case POP_PBB: | 324 | + case POP_PBB: |
277 | - case PUSH_PBB: | 325 | + case PUSH_PBB: |
278 | - case PUSH_VLAN: | 326 | + case PUSH_VLAN: |
279 | - case SET_MPLS_LABEL: | 327 | + case SET_MPLS_LABEL: |
280 | - case SET_MPLS_TC: | 328 | + case SET_MPLS_TC: |
281 | - case SET_MPLS_TTL: | 329 | + case SET_MPLS_TTL: |
282 | - case SET_NW_ECN: | 330 | + case SET_NW_ECN: |
283 | - case SET_NW_TOS: | 331 | + case SET_NW_TOS: |
284 | - case SET_NW_TTL: | 332 | + case SET_NW_TTL: |
285 | - case SET_QUEUE: | 333 | + case SET_QUEUE: |
286 | 334 | ||
287 | - case ENQUEUE: | 335 | + case ENQUEUE: |
288 | - default: | 336 | + default: |
289 | - log.warn("Action type {} not yet implemented.", act.getType()); | 337 | + log.warn("Action type {} not yet implemented.", act.getType()); |
290 | } | 338 | } |
291 | } | 339 | } |
292 | - | 340 | + return builder; |
293 | - return builder.build(); | ||
294 | } | 341 | } |
295 | 342 | ||
343 | + | ||
296 | private void handleSetField(TrafficTreatment.Builder builder, OFOxm<?> oxm) { | 344 | private void handleSetField(TrafficTreatment.Builder builder, OFOxm<?> oxm) { |
297 | switch (oxm.getMatchField().id) { | 345 | switch (oxm.getMatchField().id) { |
298 | case VLAN_PCP: | 346 | case VLAN_PCP: | ... | ... |
... | @@ -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