Committed by
Gerrit Code Review
support for corsa pipeline. EXPERIMENTAL.
Change-Id: Ic3db0a7a18f11c41c8a84f25a249dfb63109da97
Showing
12 changed files
with
383 additions
and
42 deletions
... | @@ -249,6 +249,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { | ... | @@ -249,6 +249,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { |
249 | } | 249 | } |
250 | 250 | ||
251 | @Override | 251 | @Override |
252 | + public TrafficTreatment.Builder transition(FlowRule.Type type) { | ||
253 | + return add(Instructions.transition(type)); | ||
254 | + } | ||
255 | + | ||
256 | + @Override | ||
252 | public TrafficTreatment build() { | 257 | public TrafficTreatment build() { |
253 | 258 | ||
254 | //If we are dropping should we just return an empty list? | 259 | //If we are dropping should we just return an empty list? | ... | ... |
... | @@ -40,7 +40,19 @@ public interface FlowRule { | ... | @@ -40,7 +40,19 @@ public interface FlowRule { |
40 | /* Used in flow entry for MPLS table */ | 40 | /* Used in flow entry for MPLS table */ |
41 | MPLS, | 41 | MPLS, |
42 | /* Used in flow entry for ACL table */ | 42 | /* Used in flow entry for ACL table */ |
43 | - ACL | 43 | + ACL, |
44 | + | ||
45 | + /* VLAN-to-MPLS table */ | ||
46 | + VLAN_MPLS, | ||
47 | + | ||
48 | + /* VLAN table */ | ||
49 | + VLAN, | ||
50 | + | ||
51 | + /* L2 table */ | ||
52 | + ETHER, | ||
53 | + | ||
54 | + /* Class of Service table */ | ||
55 | + COS, | ||
44 | } | 56 | } |
45 | 57 | ||
46 | //TODO: build cookie value | 58 | //TODO: build cookie value | ... | ... |
... | @@ -195,6 +195,15 @@ public interface TrafficTreatment { | ... | @@ -195,6 +195,15 @@ public interface TrafficTreatment { |
195 | */ | 195 | */ |
196 | public Builder group(GroupId groupId); | 196 | public Builder group(GroupId groupId); |
197 | 197 | ||
198 | + | ||
199 | + /** | ||
200 | + * Sets the next table type to transition to. | ||
201 | + * | ||
202 | + * @param type the table type | ||
203 | + * @return a treatement builder | ||
204 | + */ | ||
205 | + public Builder transition(FlowRule.Type type); | ||
206 | + | ||
198 | /** | 207 | /** |
199 | * Builds an immutable traffic treatment descriptor. | 208 | * Builds an immutable traffic treatment descriptor. |
200 | * | 209 | * | ... | ... |
... | @@ -50,6 +50,11 @@ public interface Instruction { | ... | @@ -50,6 +50,11 @@ public interface Instruction { |
50 | L2MODIFICATION, | 50 | L2MODIFICATION, |
51 | 51 | ||
52 | /** | 52 | /** |
53 | + * Signifies that the traffic should be passed to another table. | ||
54 | + */ | ||
55 | + TABLE, | ||
56 | + | ||
57 | + /** | ||
53 | * Signifies that the traffic should be modified in L3 way. | 58 | * Signifies that the traffic should be modified in L3 way. |
54 | */ | 59 | */ |
55 | L3MODIFICATION | 60 | L3MODIFICATION | ... | ... |
... | @@ -23,6 +23,7 @@ import java.util.Objects; | ... | @@ -23,6 +23,7 @@ import java.util.Objects; |
23 | 23 | ||
24 | import org.onosproject.core.GroupId; | 24 | import org.onosproject.core.GroupId; |
25 | import org.onosproject.net.PortNumber; | 25 | import org.onosproject.net.PortNumber; |
26 | +import org.onosproject.net.flow.FlowRule; | ||
26 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType; | 27 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType; |
27 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction; | 28 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction; |
28 | import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType; | 29 | import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType; |
... | @@ -254,6 +255,11 @@ public final class Instructions { | ... | @@ -254,6 +255,11 @@ public final class Instructions { |
254 | return new PushHeaderInstructions(L2SubType.MPLS_POP, etherType); | 255 | return new PushHeaderInstructions(L2SubType.MPLS_POP, etherType); |
255 | } | 256 | } |
256 | 257 | ||
258 | + public static Instruction transition(FlowRule.Type type) { | ||
259 | + checkNotNull(type, "Table type cannot be null"); | ||
260 | + return new TableTypeTransition(type); | ||
261 | + } | ||
262 | + | ||
257 | /* | 263 | /* |
258 | * Drop instructions | 264 | * Drop instructions |
259 | */ | 265 | */ |
... | @@ -352,6 +358,7 @@ public final class Instructions { | ... | @@ -352,6 +358,7 @@ public final class Instructions { |
352 | public Type type() { | 358 | public Type type() { |
353 | return Type.GROUP; | 359 | return Type.GROUP; |
354 | } | 360 | } |
361 | + | ||
355 | @Override | 362 | @Override |
356 | public String toString() { | 363 | public String toString() { |
357 | return toStringHelper(type().toString()) | 364 | return toStringHelper(type().toString()) |
... | @@ -377,6 +384,49 @@ public final class Instructions { | ... | @@ -377,6 +384,49 @@ public final class Instructions { |
377 | } | 384 | } |
378 | } | 385 | } |
379 | 386 | ||
387 | + // FIXME: Temporary support for this. This should probably become it's own | ||
388 | + // type like other instructions. | ||
389 | + public static class TableTypeTransition implements Instruction { | ||
390 | + private final FlowRule.Type tableType; | ||
391 | + | ||
392 | + public TableTypeTransition(FlowRule.Type type) { | ||
393 | + this.tableType = type; | ||
394 | + } | ||
395 | + | ||
396 | + @Override | ||
397 | + public Type type() { | ||
398 | + return Type.TABLE; | ||
399 | + } | ||
400 | + | ||
401 | + public FlowRule.Type tableType() { | ||
402 | + return this.tableType; | ||
403 | + } | ||
404 | + | ||
405 | + @Override | ||
406 | + public String toString() { | ||
407 | + return toStringHelper(type().toString()) | ||
408 | + .add("group ID", this.tableType).toString(); | ||
409 | + } | ||
410 | + | ||
411 | + @Override | ||
412 | + public int hashCode() { | ||
413 | + return Objects.hash(type(), tableType); | ||
414 | + } | ||
415 | + | ||
416 | + @Override | ||
417 | + public boolean equals(Object obj) { | ||
418 | + if (this == obj) { | ||
419 | + return true; | ||
420 | + } | ||
421 | + if (obj instanceof TableTypeTransition) { | ||
422 | + TableTypeTransition that = (TableTypeTransition) obj; | ||
423 | + return Objects.equals(tableType, that.tableType); | ||
424 | + | ||
425 | + } | ||
426 | + return false; | ||
427 | + } | ||
428 | + | ||
429 | + } | ||
380 | } | 430 | } |
381 | 431 | ||
382 | 432 | ... | ... |
... | @@ -32,6 +32,18 @@ public interface OpenFlowSwitch { | ... | @@ -32,6 +32,18 @@ public interface OpenFlowSwitch { |
32 | * It is used only for multi-table support switch. | 32 | * It is used only for multi-table support switch. |
33 | */ | 33 | */ |
34 | public static enum TableType { | 34 | public static enum TableType { |
35 | + /* VLAN-to-MPLS table */ | ||
36 | + VLAN_MPLS, | ||
37 | + | ||
38 | + /* VLAN table */ | ||
39 | + VLAN, | ||
40 | + | ||
41 | + /* L2 table */ | ||
42 | + ETHER, | ||
43 | + | ||
44 | + /* Class of Service table */ | ||
45 | + COS, | ||
46 | + | ||
35 | /* IP table */ | 47 | /* IP table */ |
36 | IP, | 48 | IP, |
37 | /* MPLS table */ | 49 | /* MPLS table */ |
... | @@ -40,6 +52,8 @@ public interface OpenFlowSwitch { | ... | @@ -40,6 +52,8 @@ public interface OpenFlowSwitch { |
40 | ACL, | 52 | ACL, |
41 | /* Single table */ | 53 | /* Single table */ |
42 | NONE, | 54 | NONE, |
55 | + | ||
56 | + | ||
43 | } | 57 | } |
44 | 58 | ||
45 | /** | 59 | /** | ... | ... |
1 | +/* | ||
2 | + * Copyright 2015 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onosproject.openflow.drivers; | ||
17 | + | ||
18 | +import com.google.common.collect.Lists; | ||
19 | +import org.onosproject.openflow.controller.Dpid; | ||
20 | +import org.onosproject.openflow.controller.RoleState; | ||
21 | +import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; | ||
22 | +import org.projectfloodlight.openflow.protocol.OFDescStatsReply; | ||
23 | +import org.projectfloodlight.openflow.protocol.OFFlowMod; | ||
24 | +import org.projectfloodlight.openflow.protocol.OFMessage; | ||
25 | +import org.projectfloodlight.openflow.protocol.OFType; | ||
26 | +import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; | ||
27 | +import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable; | ||
28 | +import org.projectfloodlight.openflow.types.TableId; | ||
29 | + | ||
30 | +import java.util.Collections; | ||
31 | +import java.util.List; | ||
32 | + | ||
33 | +/** | ||
34 | + * Corsa switch driver for BGP Router deployment. | ||
35 | + */ | ||
36 | +public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch { | ||
37 | + | ||
38 | + private static final int VLAN_MPLS_TABLE = 1; | ||
39 | + private static final int VLAN_TABLE = 2; | ||
40 | + private static final int MPLS_TABLE = 3; | ||
41 | + private static final int ETHER_TABLE = 4; | ||
42 | + private static final int COS_MAP_TABLE = 5; | ||
43 | + private static final int FIB_TABLE = 6; | ||
44 | + private static final int LOCAL_TABLE = 9; | ||
45 | + | ||
46 | + | ||
47 | + | ||
48 | + OFCorsaSwitchDriver(Dpid dpid, OFDescStatsReply desc) { | ||
49 | + super(dpid); | ||
50 | + | ||
51 | + setSwitchDescription(desc); | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
55 | + public void write(OFMessage msg) { | ||
56 | + this.write(Collections.singletonList(msg)); | ||
57 | + } | ||
58 | + | ||
59 | + @Override | ||
60 | + public void write(List<OFMessage> msgs) { | ||
61 | + if (role == RoleState.MASTER) { | ||
62 | + channel.write(msgs); | ||
63 | + } | ||
64 | + | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public void sendMsg(OFMessage msg, TableType type) { | ||
69 | + if (msg.getType() == OFType.FLOW_MOD) { | ||
70 | + OFFlowMod flowMod = (OFFlowMod) msg; | ||
71 | + OFFlowMod.Builder builder = flowMod.createBuilder(); | ||
72 | + List<OFInstruction> instructions = builder.getInstructions(); | ||
73 | + List<OFInstruction> newInstructions = Lists.newArrayList(); | ||
74 | + for (OFInstruction i : instructions) { | ||
75 | + if (i instanceof OFInstructionGotoTable) { | ||
76 | + OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i; | ||
77 | + TableType tid = TableType.values()[gotoTable.getTableId().getValue()]; | ||
78 | + switch (tid) { | ||
79 | + case VLAN_MPLS: | ||
80 | + newInstructions.add( | ||
81 | + gotoTable.createBuilder() | ||
82 | + .setTableId(TableId.of(VLAN_MPLS_TABLE)).build()); | ||
83 | + break; | ||
84 | + case VLAN: | ||
85 | + newInstructions.add( | ||
86 | + gotoTable.createBuilder() | ||
87 | + .setTableId(TableId.of(VLAN_TABLE)).build()); | ||
88 | + break; | ||
89 | + case ETHER: | ||
90 | + newInstructions.add( | ||
91 | + gotoTable.createBuilder() | ||
92 | + .setTableId(TableId.of(ETHER_TABLE)).build()); | ||
93 | + break; | ||
94 | + case COS: | ||
95 | + newInstructions.add( | ||
96 | + gotoTable.createBuilder() | ||
97 | + .setTableId(TableId.of(COS_MAP_TABLE)).build()); | ||
98 | + break; | ||
99 | + case IP: | ||
100 | + newInstructions.add( | ||
101 | + gotoTable.createBuilder() | ||
102 | + .setTableId(TableId.of(FIB_TABLE)).build()); | ||
103 | + break; | ||
104 | + case MPLS: | ||
105 | + newInstructions.add( | ||
106 | + gotoTable.createBuilder() | ||
107 | + .setTableId(TableId.of(MPLS_TABLE)).build()); | ||
108 | + break; | ||
109 | + case ACL: | ||
110 | + newInstructions.add( | ||
111 | + gotoTable.createBuilder() | ||
112 | + .setTableId(TableId.of(LOCAL_TABLE)).build()); | ||
113 | + break; | ||
114 | + case NONE: | ||
115 | + newInstructions.add( | ||
116 | + gotoTable.createBuilder() | ||
117 | + .setTableId(TableId.of(0)).build()); | ||
118 | + break; | ||
119 | + default: | ||
120 | + log.warn("Unknown table type: {}", tid); | ||
121 | + } | ||
122 | + | ||
123 | + } else { | ||
124 | + newInstructions.add(i); | ||
125 | + } | ||
126 | + } | ||
127 | + switch (type) { | ||
128 | + case VLAN_MPLS: | ||
129 | + builder.setTableId(TableId.of(VLAN_MPLS_TABLE)); | ||
130 | + break; | ||
131 | + case VLAN: | ||
132 | + builder.setTableId(TableId.of(VLAN_TABLE)); | ||
133 | + break; | ||
134 | + case ETHER: | ||
135 | + builder.setTableId(TableId.of(ETHER_TABLE)); | ||
136 | + break; | ||
137 | + case COS: | ||
138 | + builder.setTableId(TableId.of(COS_MAP_TABLE)); | ||
139 | + break; | ||
140 | + case IP: | ||
141 | + builder.setTableId(TableId.of(FIB_TABLE)); | ||
142 | + break; | ||
143 | + case MPLS: | ||
144 | + builder.setTableId(TableId.of(MPLS_TABLE)); | ||
145 | + break; | ||
146 | + case ACL: | ||
147 | + builder.setTableId(TableId.of(LOCAL_TABLE)); | ||
148 | + break; | ||
149 | + case NONE: | ||
150 | + builder.setTableId(TableId.of(0)); | ||
151 | + break; | ||
152 | + default: | ||
153 | + log.warn("Unknown table type: {}", type); | ||
154 | + } | ||
155 | + this.write(builder.build()); | ||
156 | + } else { | ||
157 | + this.write(msg); | ||
158 | + } | ||
159 | + } | ||
160 | + | ||
161 | + @Override | ||
162 | + public Boolean supportNxRole() { | ||
163 | + return false; | ||
164 | + } | ||
165 | + | ||
166 | + @Override | ||
167 | + public void startDriverHandshake() {} | ||
168 | + | ||
169 | + @Override | ||
170 | + public boolean isDriverHandshakeComplete() { | ||
171 | + return true; | ||
172 | + } | ||
173 | + | ||
174 | + @Override | ||
175 | + public void processDriverHandshakeMessage(OFMessage m) {} | ||
176 | +} |
... | @@ -87,7 +87,7 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch { | ... | @@ -87,7 +87,7 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch { |
87 | 87 | ||
88 | @Override | 88 | @Override |
89 | public void processDriverHandshakeMessage(OFMessage m) { | 89 | public void processDriverHandshakeMessage(OFMessage m) { |
90 | - if (!startDriverHandshakeCalled) { | 90 | + if (!startDriverHandshakeCalled) { |
91 | throw new SwitchDriverSubHandshakeNotStarted(); | 91 | throw new SwitchDriverSubHandshakeNotStarted(); |
92 | } | 92 | } |
93 | if (driverHandshakeComplete.get()) { | 93 | if (driverHandshakeComplete.get()) { | ... | ... |
... | @@ -25,10 +25,6 @@ import org.onosproject.net.flow.TrafficSelector; | ... | @@ -25,10 +25,6 @@ import org.onosproject.net.flow.TrafficSelector; |
25 | import org.onosproject.net.flow.criteria.Criteria; | 25 | import org.onosproject.net.flow.criteria.Criteria; |
26 | import org.onosproject.net.flow.criteria.Criteria.EthCriterion; | 26 | import org.onosproject.net.flow.criteria.Criteria.EthCriterion; |
27 | import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion; | 27 | import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion; |
28 | -import org.onosproject.net.flow.criteria.Criteria.IcmpCodeCriterion; | ||
29 | -import org.onosproject.net.flow.criteria.Criteria.IcmpTypeCriterion; | ||
30 | -import org.onosproject.net.flow.criteria.Criteria.Icmpv6CodeCriterion; | ||
31 | -import org.onosproject.net.flow.criteria.Criteria.Icmpv6TypeCriterion; | ||
32 | import org.onosproject.net.flow.criteria.Criteria.IPCriterion; | 28 | import org.onosproject.net.flow.criteria.Criteria.IPCriterion; |
33 | import org.onosproject.net.flow.criteria.Criteria.IPDscpCriterion; | 29 | import org.onosproject.net.flow.criteria.Criteria.IPDscpCriterion; |
34 | import org.onosproject.net.flow.criteria.Criteria.IPEcnCriterion; | 30 | import org.onosproject.net.flow.criteria.Criteria.IPEcnCriterion; |
... | @@ -36,6 +32,10 @@ import org.onosproject.net.flow.criteria.Criteria.IPProtocolCriterion; | ... | @@ -36,6 +32,10 @@ import org.onosproject.net.flow.criteria.Criteria.IPProtocolCriterion; |
36 | import org.onosproject.net.flow.criteria.Criteria.IPv6FlowLabelCriterion; | 32 | import org.onosproject.net.flow.criteria.Criteria.IPv6FlowLabelCriterion; |
37 | import org.onosproject.net.flow.criteria.Criteria.IPv6NDLinkLayerAddressCriterion; | 33 | import org.onosproject.net.flow.criteria.Criteria.IPv6NDLinkLayerAddressCriterion; |
38 | import org.onosproject.net.flow.criteria.Criteria.IPv6NDTargetAddressCriterion; | 34 | import org.onosproject.net.flow.criteria.Criteria.IPv6NDTargetAddressCriterion; |
35 | +import org.onosproject.net.flow.criteria.Criteria.IcmpCodeCriterion; | ||
36 | +import org.onosproject.net.flow.criteria.Criteria.IcmpTypeCriterion; | ||
37 | +import org.onosproject.net.flow.criteria.Criteria.Icmpv6CodeCriterion; | ||
38 | +import org.onosproject.net.flow.criteria.Criteria.Icmpv6TypeCriterion; | ||
39 | import org.onosproject.net.flow.criteria.Criteria.LambdaCriterion; | 39 | import org.onosproject.net.flow.criteria.Criteria.LambdaCriterion; |
40 | import org.onosproject.net.flow.criteria.Criteria.MetadataCriterion; | 40 | import org.onosproject.net.flow.criteria.Criteria.MetadataCriterion; |
41 | import org.onosproject.net.flow.criteria.Criteria.PortCriterion; | 41 | import org.onosproject.net.flow.criteria.Criteria.PortCriterion; |
... | @@ -99,7 +99,8 @@ public abstract class FlowModBuilder { | ... | @@ -99,7 +99,8 @@ public abstract class FlowModBuilder { |
99 | * @return the new flow mod builder | 99 | * @return the new flow mod builder |
100 | */ | 100 | */ |
101 | public static FlowModBuilder builder(FlowRule flowRule, | 101 | public static FlowModBuilder builder(FlowRule flowRule, |
102 | - OFFactory factory, Optional<Long> xid) { | 102 | + OFFactory factory, |
103 | + Optional<Long> xid) { | ||
103 | switch (factory.getVersion()) { | 104 | switch (factory.getVersion()) { |
104 | case OF_10: | 105 | case OF_10: |
105 | return new FlowModBuilderVer10(flowRule, factory, xid); | 106 | return new FlowModBuilderVer10(flowRule, factory, xid); | ... | ... |
providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
... | @@ -21,8 +21,9 @@ import org.onosproject.net.PortNumber; | ... | @@ -21,8 +21,9 @@ import org.onosproject.net.PortNumber; |
21 | import org.onosproject.net.flow.FlowRule; | 21 | import org.onosproject.net.flow.FlowRule; |
22 | import org.onosproject.net.flow.TrafficTreatment; | 22 | import org.onosproject.net.flow.TrafficTreatment; |
23 | import org.onosproject.net.flow.instructions.Instruction; | 23 | import org.onosproject.net.flow.instructions.Instruction; |
24 | -import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | 24 | +import org.onosproject.net.flow.instructions.Instructions; |
25 | import org.onosproject.net.flow.instructions.Instructions.GroupInstruction; | 25 | import org.onosproject.net.flow.instructions.Instructions.GroupInstruction; |
26 | +import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | ||
26 | import org.onosproject.net.flow.instructions.L0ModificationInstruction; | 27 | import org.onosproject.net.flow.instructions.L0ModificationInstruction; |
27 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction; | 28 | import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction; |
28 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; | 29 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; |
... | @@ -34,6 +35,7 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeade | ... | @@ -34,6 +35,7 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeade |
34 | import org.onosproject.net.flow.instructions.L3ModificationInstruction; | 35 | import org.onosproject.net.flow.instructions.L3ModificationInstruction; |
35 | import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; | 36 | import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; |
36 | import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; | 37 | import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; |
38 | +import org.onosproject.openflow.controller.OpenFlowSwitch; | ||
37 | import org.projectfloodlight.openflow.protocol.OFFactory; | 39 | import org.projectfloodlight.openflow.protocol.OFFactory; |
38 | import org.projectfloodlight.openflow.protocol.OFFlowAdd; | 40 | import org.projectfloodlight.openflow.protocol.OFFlowAdd; |
39 | import org.projectfloodlight.openflow.protocol.OFFlowDelete; | 41 | import org.projectfloodlight.openflow.protocol.OFFlowDelete; |
... | @@ -42,6 +44,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFlags; | ... | @@ -42,6 +44,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFlags; |
42 | import org.projectfloodlight.openflow.protocol.action.OFAction; | 44 | import org.projectfloodlight.openflow.protocol.action.OFAction; |
43 | import org.projectfloodlight.openflow.protocol.action.OFActionGroup; | 45 | import org.projectfloodlight.openflow.protocol.action.OFActionGroup; |
44 | import org.projectfloodlight.openflow.protocol.action.OFActionOutput; | 46 | import org.projectfloodlight.openflow.protocol.action.OFActionOutput; |
47 | +import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; | ||
45 | import org.projectfloodlight.openflow.protocol.match.Match; | 48 | import org.projectfloodlight.openflow.protocol.match.Match; |
46 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; | 49 | import org.projectfloodlight.openflow.protocol.oxm.OFOxm; |
47 | import org.projectfloodlight.openflow.types.CircuitSignalID; | 50 | import org.projectfloodlight.openflow.types.CircuitSignalID; |
... | @@ -54,6 +57,7 @@ import org.projectfloodlight.openflow.types.OFBufferId; | ... | @@ -54,6 +57,7 @@ import org.projectfloodlight.openflow.types.OFBufferId; |
54 | import org.projectfloodlight.openflow.types.OFGroup; | 57 | import org.projectfloodlight.openflow.types.OFGroup; |
55 | import org.projectfloodlight.openflow.types.OFPort; | 58 | import org.projectfloodlight.openflow.types.OFPort; |
56 | import org.projectfloodlight.openflow.types.OFVlanVidMatch; | 59 | import org.projectfloodlight.openflow.types.OFVlanVidMatch; |
60 | +import org.projectfloodlight.openflow.types.TableId; | ||
57 | import org.projectfloodlight.openflow.types.U32; | 61 | import org.projectfloodlight.openflow.types.U32; |
58 | import org.projectfloodlight.openflow.types.U64; | 62 | import org.projectfloodlight.openflow.types.U64; |
59 | import org.projectfloodlight.openflow.types.VlanPcp; | 63 | import org.projectfloodlight.openflow.types.VlanPcp; |
... | @@ -92,7 +96,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -92,7 +96,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
92 | public OFFlowAdd buildFlowAdd() { | 96 | public OFFlowAdd buildFlowAdd() { |
93 | Match match = buildMatch(); | 97 | Match match = buildMatch(); |
94 | List<OFAction> actions = buildActions(); | 98 | List<OFAction> actions = buildActions(); |
95 | - | 99 | + List<OFInstruction> instructions = buildInstructions(); |
96 | // FIXME had to revert back to using apply-actions instead of | 100 | // FIXME had to revert back to using apply-actions instead of |
97 | // write-actions because LINC-OE apparently doesn't support | 101 | // write-actions because LINC-OE apparently doesn't support |
98 | // write-actions. I would prefer to change this back in the future | 102 | // write-actions. I would prefer to change this back in the future |
... | @@ -109,7 +113,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -109,7 +113,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
109 | .setCookie(U64.of(cookie)) | 113 | .setCookie(U64.of(cookie)) |
110 | .setBufferId(OFBufferId.NO_BUFFER) | 114 | .setBufferId(OFBufferId.NO_BUFFER) |
111 | .setActions(actions) | 115 | .setActions(actions) |
112 | - //.setInstructions(Collections.singletonList(writeActions)) | 116 | + .setInstructions(instructions) |
113 | .setMatch(match) | 117 | .setMatch(match) |
114 | .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) | 118 | .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) |
115 | .setPriority(flowRule().priority()) | 119 | .setPriority(flowRule().priority()) |
... | @@ -122,6 +126,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -122,6 +126,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
122 | public OFFlowMod buildFlowMod() { | 126 | public OFFlowMod buildFlowMod() { |
123 | Match match = buildMatch(); | 127 | Match match = buildMatch(); |
124 | List<OFAction> actions = buildActions(); | 128 | List<OFAction> actions = buildActions(); |
129 | + List<OFInstruction> instructions = buildInstructions(); | ||
125 | //OFInstruction writeActions = | 130 | //OFInstruction writeActions = |
126 | //factory().instructions().writeActions(actions); | 131 | //factory().instructions().writeActions(actions); |
127 | 132 | ||
... | @@ -133,7 +138,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -133,7 +138,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
133 | .setCookie(U64.of(cookie)) | 138 | .setCookie(U64.of(cookie)) |
134 | .setBufferId(OFBufferId.NO_BUFFER) | 139 | .setBufferId(OFBufferId.NO_BUFFER) |
135 | .setActions(actions) | 140 | .setActions(actions) |
136 | - //.setInstructions(Collections.singletonList(writeActions)) | 141 | + .setInstructions(instructions) |
137 | .setMatch(match) | 142 | .setMatch(match) |
138 | .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) | 143 | .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) |
139 | .setPriority(flowRule().priority()) | 144 | .setPriority(flowRule().priority()) |
... | @@ -145,7 +150,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -145,7 +150,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
145 | @Override | 150 | @Override |
146 | public OFFlowDelete buildFlowDel() { | 151 | public OFFlowDelete buildFlowDel() { |
147 | Match match = buildMatch(); | 152 | Match match = buildMatch(); |
148 | - List<OFAction> actions = buildActions(); | ||
149 | 153 | ||
150 | long cookie = flowRule().id().value(); | 154 | long cookie = flowRule().id().value(); |
151 | 155 | ||
... | @@ -161,6 +165,24 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -161,6 +165,24 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
161 | return fm; | 165 | return fm; |
162 | } | 166 | } |
163 | 167 | ||
168 | + | ||
169 | + private List<OFInstruction> buildInstructions() { | ||
170 | + List<OFInstruction> instructions = new LinkedList<>(); | ||
171 | + if (treatment == null) { | ||
172 | + return instructions; | ||
173 | + } | ||
174 | + for (Instruction i : treatment.instructions()) { | ||
175 | + switch (i.type()) { | ||
176 | + case TABLE: | ||
177 | + instructions.add(buildTableGoto(((Instructions.TableTypeTransition) i))); | ||
178 | + break; | ||
179 | + default: | ||
180 | + break; | ||
181 | + } | ||
182 | + } | ||
183 | + return instructions; | ||
184 | + } | ||
185 | + | ||
164 | private List<OFAction> buildActions() { | 186 | private List<OFAction> buildActions() { |
165 | List<OFAction> actions = new LinkedList<>(); | 187 | List<OFAction> actions = new LinkedList<>(); |
166 | if (treatment == null) { | 188 | if (treatment == null) { |
... | @@ -168,41 +190,73 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -168,41 +190,73 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
168 | } | 190 | } |
169 | for (Instruction i : treatment.instructions()) { | 191 | for (Instruction i : treatment.instructions()) { |
170 | switch (i.type()) { | 192 | switch (i.type()) { |
171 | - case DROP: | 193 | + case DROP: |
172 | - log.warn("Saw drop action; assigning drop action"); | 194 | + log.warn("Saw drop action; assigning drop action"); |
173 | - return new LinkedList<>(); | 195 | + return new LinkedList<>(); |
174 | - case L0MODIFICATION: | 196 | + case L0MODIFICATION: |
175 | - actions.add(buildL0Modification(i)); | 197 | + actions.add(buildL0Modification(i)); |
176 | - break; | 198 | + break; |
177 | - case L2MODIFICATION: | 199 | + case L2MODIFICATION: |
178 | - actions.add(buildL2Modification(i)); | 200 | + actions.add(buildL2Modification(i)); |
179 | - break; | 201 | + break; |
180 | - case L3MODIFICATION: | 202 | + case L3MODIFICATION: |
181 | - actions.add(buildL3Modification(i)); | 203 | + actions.add(buildL3Modification(i)); |
182 | - break; | 204 | + break; |
183 | - case OUTPUT: | 205 | + case OUTPUT: |
184 | - OutputInstruction out = (OutputInstruction) i; | 206 | + OutputInstruction out = (OutputInstruction) i; |
185 | - OFActionOutput.Builder action = factory().actions().buildOutput() | 207 | + OFActionOutput.Builder action = factory().actions().buildOutput() |
186 | - .setPort(OFPort.of((int) out.port().toLong())); | 208 | + .setPort(OFPort.of((int) out.port().toLong())); |
187 | - if (out.port().equals(PortNumber.CONTROLLER)) { | 209 | + if (out.port().equals(PortNumber.CONTROLLER)) { |
188 | - action.setMaxLen(OFPCML_NO_BUFFER); | 210 | + action.setMaxLen(OFPCML_NO_BUFFER); |
189 | - } | 211 | + } |
190 | - actions.add(action.build()); | 212 | + actions.add(action.build()); |
191 | - break; | 213 | + break; |
192 | - case GROUP: | 214 | + case GROUP: |
193 | - GroupInstruction group = (GroupInstruction) i; | 215 | + GroupInstruction group = (GroupInstruction) i; |
194 | - OFActionGroup.Builder groupBuilder = factory().actions().buildGroup() | 216 | + OFActionGroup.Builder groupBuilder = factory().actions().buildGroup() |
195 | - .setGroup(OFGroup.of(group.groupId().id())); | 217 | + .setGroup(OFGroup.of(group.groupId().id())); |
196 | - actions.add(groupBuilder.build()); | 218 | + actions.add(groupBuilder.build()); |
197 | - break; | 219 | + break; |
198 | - default: | 220 | + default: |
199 | - log.warn("Instruction type {} not yet implemented.", i.type()); | 221 | + log.warn("Instruction type {} not yet implemented.", i.type()); |
200 | } | 222 | } |
201 | } | 223 | } |
202 | 224 | ||
203 | return actions; | 225 | return actions; |
204 | } | 226 | } |
205 | 227 | ||
228 | + private OFInstruction buildTableGoto(Instructions.TableTypeTransition i) { | ||
229 | + OFInstruction instruction = factory().instructions().gotoTable( | ||
230 | + TableId.of(getTableType(i.tableType()).ordinal())); | ||
231 | + return instruction; | ||
232 | + } | ||
233 | + | ||
234 | + // FIXME: this has to go as well perhaps when we implement the SelectorService. | ||
235 | + private OpenFlowSwitch.TableType getTableType(FlowRule.Type type) { | ||
236 | + switch (type) { | ||
237 | + | ||
238 | + case DEFAULT: | ||
239 | + return OpenFlowSwitch.TableType.NONE; | ||
240 | + case IP: | ||
241 | + return OpenFlowSwitch.TableType.IP; | ||
242 | + case MPLS: | ||
243 | + return OpenFlowSwitch.TableType.MPLS; | ||
244 | + case ACL: | ||
245 | + return OpenFlowSwitch.TableType.ACL; | ||
246 | + case VLAN_MPLS: | ||
247 | + return OpenFlowSwitch.TableType.VLAN_MPLS; | ||
248 | + case VLAN: | ||
249 | + return OpenFlowSwitch.TableType.VLAN; | ||
250 | + case ETHER: | ||
251 | + return OpenFlowSwitch.TableType.ETHER; | ||
252 | + case COS: | ||
253 | + return OpenFlowSwitch.TableType.COS; | ||
254 | + default: | ||
255 | + return OpenFlowSwitch.TableType.NONE; | ||
256 | + } | ||
257 | + } | ||
258 | + | ||
259 | + | ||
206 | private OFAction buildL0Modification(Instruction i) { | 260 | private OFAction buildL0Modification(Instruction i) { |
207 | L0ModificationInstruction l0m = (L0ModificationInstruction) i; | 261 | L0ModificationInstruction l0m = (L0ModificationInstruction) i; |
208 | switch (l0m.subtype()) { | 262 | switch (l0m.subtype()) { | ... | ... |
... | @@ -159,8 +159,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -159,8 +159,10 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr |
159 | sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(), | 159 | sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(), |
160 | Optional.empty()).buildFlowAdd()); | 160 | Optional.empty()).buildFlowAdd()); |
161 | } else { | 161 | } else { |
162 | + OpenFlowSwitch.TableType type = getTableType(flowRule.type()); | ||
162 | sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(), | 163 | sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(), |
163 | - Optional.empty()).buildFlowAdd(), getTableType(flowRule.type())); | 164 | + Optional.empty()).buildFlowAdd(), |
165 | + type); | ||
164 | } | 166 | } |
165 | } | 167 | } |
166 | 168 | ||
... | @@ -230,12 +232,23 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr | ... | @@ -230,12 +232,23 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr |
230 | 232 | ||
231 | private OpenFlowSwitch.TableType getTableType(FlowRule.Type type) { | 233 | private OpenFlowSwitch.TableType getTableType(FlowRule.Type type) { |
232 | switch (type) { | 234 | switch (type) { |
235 | + | ||
236 | + case DEFAULT: | ||
237 | + return OpenFlowSwitch.TableType.NONE; | ||
233 | case IP: | 238 | case IP: |
234 | return OpenFlowSwitch.TableType.IP; | 239 | return OpenFlowSwitch.TableType.IP; |
235 | case MPLS: | 240 | case MPLS: |
236 | return OpenFlowSwitch.TableType.MPLS; | 241 | return OpenFlowSwitch.TableType.MPLS; |
237 | case ACL: | 242 | case ACL: |
238 | return OpenFlowSwitch.TableType.ACL; | 243 | return OpenFlowSwitch.TableType.ACL; |
244 | + case VLAN_MPLS: | ||
245 | + return OpenFlowSwitch.TableType.VLAN_MPLS; | ||
246 | + case VLAN: | ||
247 | + return OpenFlowSwitch.TableType.VLAN; | ||
248 | + case ETHER: | ||
249 | + return OpenFlowSwitch.TableType.ETHER; | ||
250 | + case COS: | ||
251 | + return OpenFlowSwitch.TableType.COS; | ||
239 | default: | 252 | default: |
240 | return OpenFlowSwitch.TableType.NONE; | 253 | return OpenFlowSwitch.TableType.NONE; |
241 | } | 254 | } | ... | ... |
-
Please register or login to post a comment